You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2017/11/24 10:59:09 UTC
[1/8] celix git commit: CELIX-417: Refactors CMake usage for the RSA
bundles
Repository: celix
Updated Branches:
refs/heads/feature/CELIX-417-cmake-refactor 2a670f265 -> 486d4f0d5
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c b/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c
new file mode 100644
index 0000000..0b8dcf7
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c
@@ -0,0 +1,402 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <stdlib.h>
+#include <jansson.h>
+#include <json_rpc.h>
+#include <assert.h>
+#include "version.h"
+#include "json_serializer.h"
+#include "dyn_interface.h"
+#include "import_registration.h"
+#include "import_registration_dfi.h"
+
+struct import_registration {
+ bundle_context_pt context;
+ endpoint_description_pt endpoint; //TODO owner? -> free when destroyed
+ const char *classObject; //NOTE owned by endpoint
+ version_pt version;
+
+ celix_thread_mutex_t mutex; //protects send & sendhandle
+ send_func_type send;
+ void *sendHandle;
+
+ service_factory_pt factory;
+ service_registration_pt factoryReg;
+
+ hash_map_pt proxies; //key -> bundle, value -> service_proxy
+ celix_thread_mutex_t proxiesMutex; //protects proxies
+};
+
+struct service_proxy {
+ dyn_interface_type *intf;
+ void *service;
+ size_t count;
+};
+
+static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle,
+ struct service_proxy **proxy);
+static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal);
+static void importRegistration_destroyProxy(struct service_proxy *proxy);
+static void importRegistration_clearProxies(import_registration_pt import);
+
+celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt endpoint, const char *classObject, const char* serviceVersion,
+ import_registration_pt *out) {
+ celix_status_t status = CELIX_SUCCESS;
+ import_registration_pt reg = calloc(1, sizeof(*reg));
+
+ if (reg != NULL) {
+ reg->factory = calloc(1, sizeof(*reg->factory));
+ }
+
+ if (reg != NULL && reg->factory != NULL) {
+ reg->context = context;
+ reg->endpoint = endpoint;
+ reg->classObject = classObject;
+ reg->proxies = hashMap_create(NULL, NULL, NULL, NULL);
+
+ celixThreadMutex_create(®->mutex, NULL);
+ celixThreadMutex_create(®->proxiesMutex, NULL);
+ status = version_createVersionFromString((char*)serviceVersion,&(reg->version));
+
+ reg->factory->handle = reg;
+ reg->factory->getService = (void *)importRegistration_getService;
+ reg->factory->ungetService = (void *)importRegistration_ungetService;
+ } else {
+ status = CELIX_ENOMEM;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ //printf("IMPORT REGISTRATION IS %p\n", reg);
+ *out = reg;
+ }
+ else{
+ importRegistration_destroy(reg);
+ }
+
+ return status;
+}
+
+
+celix_status_t importRegistration_setSendFn(import_registration_pt reg,
+ send_func_type send,
+ void *handle) {
+ celixThreadMutex_lock(®->mutex);
+ reg->send = send;
+ reg->sendHandle = handle;
+ celixThreadMutex_unlock(®->mutex);
+
+ return CELIX_SUCCESS;
+}
+
+static void importRegistration_clearProxies(import_registration_pt import) {
+ if (import != NULL) {
+ pthread_mutex_lock(&import->proxiesMutex);
+ if (import->proxies != NULL) {
+ hash_map_iterator_pt iter = hashMapIterator_create(import->proxies);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ struct service_proxy *proxy = hashMapEntry_getValue(entry);
+ importRegistration_destroyProxy(proxy);
+ }
+ hashMapIterator_destroy(iter);
+ }
+ pthread_mutex_unlock(&import->proxiesMutex);
+ }
+}
+
+void importRegistration_destroy(import_registration_pt import) {
+ if (import != NULL) {
+ if (import->proxies != NULL) {
+ hashMap_destroy(import->proxies, false, false);
+ import->proxies = NULL;
+ }
+
+ pthread_mutex_destroy(&import->mutex);
+ pthread_mutex_destroy(&import->proxiesMutex);
+
+ if (import->factory != NULL) {
+ free(import->factory);
+ }
+
+ if(import->version!=NULL){
+ version_destroy(import->version);
+ }
+ free(import);
+ }
+}
+
+celix_status_t importRegistration_start(import_registration_pt import) {
+ celix_status_t status = CELIX_SUCCESS;
+ if (import->factoryReg == NULL && import->factory != NULL) {
+ properties_pt props = NULL;
+ properties_copy(import->endpoint->properties, &props);
+ status = bundleContext_registerServiceFactory(import->context, (char *)import->classObject, import->factory, props, &import->factoryReg);
+ } else {
+ status = CELIX_ILLEGAL_STATE;
+ }
+ return status;
+}
+
+celix_status_t importRegistration_stop(import_registration_pt import) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ if (import->factoryReg != NULL) {
+ serviceRegistration_unregister(import->factoryReg);
+ import->factoryReg = NULL;
+ }
+
+ importRegistration_clearProxies(import);
+
+ return status;
+}
+
+
+celix_status_t importRegistration_getService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ /*
+ module_pt module = NULL;
+ char *name = NULL;
+ bundle_getCurrentModule(bundle, &module);
+ module_getSymbolicName(module, &name);
+ printf("getting service for bundle '%s'\n", name);
+ */
+
+
+ pthread_mutex_lock(&import->proxiesMutex);
+ struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
+ if (proxy == NULL) {
+ status = importRegistration_createProxy(import, bundle, &proxy);
+ if (status == CELIX_SUCCESS) {
+ hashMap_put(import->proxies, bundle, proxy);
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ proxy->count += 1;
+ *out = proxy->service;
+ }
+ pthread_mutex_unlock(&import->proxiesMutex);
+
+ return status;
+}
+
+static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle, struct service_proxy **out) {
+ celix_status_t status;
+ dyn_interface_type* intf = NULL;
+ FILE *descriptor = NULL;
+
+ status = dfi_findDescriptor(import->context, bundle, import->classObject, &descriptor);
+
+ if (status != CELIX_SUCCESS || descriptor == NULL) {
+ //TODO use log helper logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", import->classObject);
+ fprintf(stderr, "RSA_DFI: Cannot find/open descriptor for '%s'", import->classObject);
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ int rc = dynInterface_parse(descriptor, &intf);
+ fclose(descriptor);
+ if (rc != 0 || intf==NULL) {
+ return CELIX_BUNDLE_EXCEPTION;
+ }
+ }
+
+ /* Check if the imported service version is compatible with the one in the consumer descriptor */
+ version_pt consumerVersion = NULL;
+ bool isCompatible = false;
+ dynInterface_getVersion(intf,&consumerVersion);
+ version_isCompatible(consumerVersion,import->version,&isCompatible);
+
+ if(!isCompatible){
+ char* cVerString = NULL;
+ char* pVerString = NULL;
+ version_toString(consumerVersion,&cVerString);
+ version_toString(import->version,&pVerString);
+ printf("Service version mismatch: consumer has %s, provider has %s. NOT creating proxy.\n",cVerString,pVerString);
+ dynInterface_destroy(intf);
+ free(cVerString);
+ free(pVerString);
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+
+ struct service_proxy *proxy = NULL;
+ if (status == CELIX_SUCCESS) {
+ proxy = calloc(1, sizeof(*proxy));
+ if (proxy == NULL) {
+ status = CELIX_ENOMEM;
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ proxy->intf = intf;
+ size_t count = dynInterface_nrOfMethods(proxy->intf);
+ proxy->service = calloc(1 + count, sizeof(void *));
+ if (proxy->service == NULL) {
+ status = CELIX_ENOMEM;
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ void **serv = proxy->service;
+ serv[0] = import;
+
+ struct methods_head *list = NULL;
+ dynInterface_methods(proxy->intf, &list);
+ struct method_entry *entry = NULL;
+ void (*fn)(void) = NULL;
+ int index = 0;
+ TAILQ_FOREACH(entry, list, entries) {
+ int rc = dynFunction_createClosure(entry->dynFunc, importRegistration_proxyFunc, entry, &fn);
+ serv[index + 1] = fn;
+ index += 1;
+
+ if (rc != 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ break;
+ }
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ *out = proxy;
+ } else if (proxy != NULL) {
+ if (proxy->intf != NULL) {
+ dynInterface_destroy(proxy->intf);
+ proxy->intf = NULL;
+ }
+ free(proxy->service);
+ free(proxy);
+ }
+
+ return status;
+}
+
+static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal) {
+ int status = CELIX_SUCCESS;
+ struct method_entry *entry = userData;
+ import_registration_pt import = *((void **)args[0]);
+
+ if (import == NULL || import->send == NULL) {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+
+
+ char *invokeRequest = NULL;
+ if (status == CELIX_SUCCESS) {
+ status = jsonRpc_prepareInvokeRequest(entry->dynFunc, entry->id, args, &invokeRequest);
+ //printf("Need to send following json '%s'\n", invokeRequest);
+ }
+
+
+ if (status == CELIX_SUCCESS) {
+ char *reply = NULL;
+ int rc = 0;
+ //printf("sending request\n");
+ celixThreadMutex_lock(&import->mutex);
+ if (import->send != NULL) {
+ import->send(import->sendHandle, import->endpoint, invokeRequest, &reply, &rc);
+ }
+ celixThreadMutex_unlock(&import->mutex);
+ //printf("request sended. got reply '%s' with status %i\n", reply, rc);
+
+ if (rc == 0) {
+ //fjprintf("Handling reply '%s'\n", reply);
+ status = jsonRpc_handleReply(entry->dynFunc, reply, args);
+ }
+
+ *(int *) returnVal = rc;
+
+ free(invokeRequest); //Allocated by json_dumps in jsonRpc_prepareInvokeRequest
+ free(reply); //Allocated by json_dumps in remoteServiceAdmin_send through curl call
+ }
+
+ if (status != CELIX_SUCCESS) {
+ //TODO log error
+ }
+}
+
+celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ assert(import != NULL);
+ assert(import->proxies != NULL);
+
+ pthread_mutex_lock(&import->proxiesMutex);
+
+ struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
+ if (proxy != NULL) {
+ if (*out == proxy->service) {
+ proxy->count -= 1;
+ } else {
+ status = CELIX_ILLEGAL_ARGUMENT;
+ }
+
+ if (proxy->count == 0) {
+ hashMap_remove(import->proxies, bundle);
+ importRegistration_destroyProxy(proxy);
+ }
+ }
+
+ pthread_mutex_unlock(&import->proxiesMutex);
+
+ return status;
+}
+
+static void importRegistration_destroyProxy(struct service_proxy *proxy) {
+ if (proxy != NULL) {
+ if (proxy->intf != NULL) {
+ dynInterface_destroy(proxy->intf);
+ }
+ if (proxy->service != NULL) {
+ free(proxy->service);
+ }
+ free(proxy);
+ }
+}
+
+
+celix_status_t importRegistration_close(import_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ importRegistration_stop(registration);
+ return status;
+}
+
+celix_status_t importRegistration_getException(import_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ //TODO
+ return status;
+}
+
+celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
+ celix_status_t status = CELIX_SUCCESS;
+ //TODO
+ return status;
+}
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+celix_status_t importReference_getImportedService(import_reference_pt reference) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h b/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h
new file mode 100644
index 0000000..aac4bc7
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h
@@ -0,0 +1,44 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef CELIX_IMPORT_REGISTRATION_DFI_H
+#define CELIX_IMPORT_REGISTRATION_DFI_H
+
+#include "import_registration.h"
+#include "dfi_utils.h"
+
+#include <celix_errno.h>
+
+typedef void (*send_func_type)(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
+
+celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt description, const char *classObject, const char* serviceVersion,
+ import_registration_pt *import);
+celix_status_t importRegistration_close(import_registration_pt import);
+void importRegistration_destroy(import_registration_pt import);
+
+celix_status_t importRegistration_setSendFn(import_registration_pt reg,
+ send_func_type,
+ void *handle);
+celix_status_t importRegistration_start(import_registration_pt import);
+celix_status_t importRegistration_stop(import_registration_pt import);
+
+celix_status_t importRegistration_getService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **service);
+celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **service);
+
+#endif //CELIX_IMPORT_REGISTRATION_DFI_H
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c
new file mode 100644
index 0000000..d4cc765
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c
@@ -0,0 +1,124 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_activator.c
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+#include <remote_service_admin.h>
+
+#include "remote_service_admin_dfi.h"
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+
+#include "export_registration_dfi.h"
+#include "import_registration_dfi.h"
+
+struct activator {
+ remote_service_admin_pt admin;
+ remote_service_admin_service_pt adminService;
+ service_registration_pt registration;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator;
+
+ activator = calloc(1, sizeof(*activator));
+ if (!activator) {
+ status = CELIX_ENOMEM;
+ } else {
+ activator->admin = NULL;
+ activator->registration = NULL;
+
+ *userData = activator;
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+ remote_service_admin_service_pt remoteServiceAdmin = NULL;
+
+ status = remoteServiceAdmin_create(context, &activator->admin);
+ if (status == CELIX_SUCCESS) {
+ remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
+ if (!remoteServiceAdmin) {
+ status = CELIX_ENOMEM;
+ } else {
+ remoteServiceAdmin->admin = activator->admin;
+ remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
+
+ remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
+ remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
+ remoteServiceAdmin->importService = remoteServiceAdmin_importService;
+
+ remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
+ remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
+
+ remoteServiceAdmin->exportRegistration_close = remoteServiceAdmin_removeExportedService;
+ remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
+ remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
+
+ remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
+ remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
+
+ remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
+ remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
+ remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
+
+ status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
+ activator->adminService = remoteServiceAdmin;
+ }
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ serviceRegistration_unregister(activator->registration);
+ activator->registration = NULL;
+
+ remoteServiceAdmin_stop(activator->admin);
+ remoteServiceAdmin_destroy(&activator->admin);
+
+ free(activator->adminService);
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ free(activator);
+
+ return status;
+}
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
new file mode 100644
index 0000000..6effc94
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
@@ -0,0 +1,771 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_impl.c
+ *
+ * \date May 21, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include <string.h>
+#include <uuid/uuid.h>
+#include <curl/curl.h>
+
+#include <jansson.h>
+#include "json_serializer.h"
+#include "remote_service_admin.h"
+
+#include "import_registration_dfi.h"
+#include "export_registration_dfi.h"
+#include "remote_service_admin_dfi.h"
+#include "json_rpc.h"
+
+#include "remote_constants.h"
+#include "constants.h"
+#include "civetweb.h"
+
+// defines how often the webserver is restarted (with an increased port number)
+#define MAX_NUMBER_OF_RESTARTS 5
+
+
+#define RSA_LOG_ERROR(admin, msg, ...) \
+ logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
+
+#define RSA_LOG_WARNING(admin, msg, ...) \
+ logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
+
+#define RSA_LOG_DEBUG(admin, msg, ...) \
+ logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
+
+struct remote_service_admin {
+ bundle_context_pt context;
+ log_helper_pt loghelper;
+
+ celix_thread_mutex_t exportedServicesLock;
+ hash_map_pt exportedServices;
+
+ celix_thread_mutex_t importedServicesLock;
+ array_list_pt importedServices;
+
+ char *port;
+ char *ip;
+
+ struct mg_context *ctx;
+};
+
+struct post {
+ const char *readptr;
+ int size;
+};
+
+struct get {
+ char *writeptr;
+ int size;
+};
+
+#define OSGI_RSA_REMOTE_PROXY_FACTORY "remote_proxy_factory"
+#define OSGI_RSA_REMOTE_PROXY_TIMEOUT "remote_proxy_timeout"
+
+static const char *data_response_headers =
+ "HTTP/1.1 200 OK\r\n"
+ "Cache: no-cache\r\n"
+ "Content-Type: application/json\r\n"
+ "\r\n";
+
+static const char *no_content_response_headers =
+ "HTTP/1.1 204 OK\r\n";
+
+// TODO do we need to specify a non-Amdatu specific configuration type?!
+static const char * const CONFIGURATION_TYPE = "org.amdatu.remote.admin.http";
+static const char * const ENDPOINT_URL = "org.amdatu.remote.admin.http.url";
+
+static const char *DEFAULT_PORT = "8888";
+static const char *DEFAULT_IP = "127.0.0.1";
+
+static const unsigned int DEFAULT_TIMEOUT = 0;
+
+static int remoteServiceAdmin_callback(struct mg_connection *conn);
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, char *interface, endpoint_description_pt *description);
+static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
+static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip);
+static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp);
+static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp);
+static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...);
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *admin = calloc(1, sizeof(**admin));
+
+ if (!*admin) {
+ status = CELIX_ENOMEM;
+ } else {
+ unsigned int port_counter = 0;
+ const char *port = NULL;
+ const char *ip = NULL;
+ char *detectedIp = NULL;
+ (*admin)->context = context;
+ (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
+ arrayList_create(&(*admin)->importedServices);
+
+ celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
+ celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
+
+ if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
+ logHelper_start((*admin)->loghelper);
+ dynCommon_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ dynType_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ dynFunction_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ dynInterface_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ jsonSerializer_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ jsonRpc_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ }
+
+ bundleContext_getProperty(context, "RSA_PORT", &port);
+ if (port == NULL) {
+ port = (char *)DEFAULT_PORT;
+ }
+
+ bundleContext_getProperty(context, "RSA_IP", &ip);
+ if (ip == NULL) {
+ const char *interface = NULL;
+
+ bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
+ if ((interface != NULL) && (remoteServiceAdmin_getIpAdress((char*)interface, &detectedIp) != CELIX_SUCCESS)) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: Could not retrieve IP adress for interface %s", interface);
+ }
+
+ if (ip == NULL) {
+ remoteServiceAdmin_getIpAdress(NULL, &detectedIp);
+ }
+
+ ip = detectedIp;
+ }
+
+ if (ip != NULL) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Using %s for service annunciation", ip);
+ (*admin)->ip = strdup(ip);
+ }
+ else {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No IP address for service annunciation set. Using %s", DEFAULT_IP);
+ (*admin)->ip = strdup((char*) DEFAULT_IP);
+ }
+
+ if (detectedIp != NULL) {
+ free(detectedIp);
+ }
+
+ // Prepare callbacks structure. We have only one callback, the rest are NULL.
+ struct mg_callbacks callbacks;
+ memset(&callbacks, 0, sizeof(callbacks));
+ callbacks.begin_request = remoteServiceAdmin_callback;
+
+ char newPort[10];
+
+ do {
+
+ const char *options[] = { "listening_ports", port, "num_threads", "5", NULL};
+
+ (*admin)->ctx = mg_start(&callbacks, (*admin), options);
+
+ if ((*admin)->ctx != NULL) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Start webserver: %s", port);
+ (*admin)->port = strdup(port);
+
+ }
+ else {
+ errno = 0;
+ char* endptr = (char*)port;
+ int currentPort = strtol(port, &endptr, 10);
+
+ if (*endptr || errno != 0) {
+ currentPort = strtol(DEFAULT_PORT, NULL, 10);
+ }
+
+ port_counter++;
+ snprintf(&newPort[0], 6, "%d", (currentPort+1));
+
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting rsa server on port %s - retrying on port %s...", port, newPort);
+ port = newPort;
+ }
+ } while(((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS));
+
+ }
+
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin)
+{
+ celix_status_t status = CELIX_SUCCESS;
+
+ free((*admin)->ip);
+ free((*admin)->port);
+ free(*admin);
+
+ //TODO destroy exports/imports
+
+ *admin = NULL;
+
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(admin->exportedServices);
+ while (hashMapIterator_hasNext(iter)) {
+ array_list_pt exports = hashMapIterator_nextValue(iter);
+ int i;
+ for (i = 0; i < arrayList_size(exports); i++) {
+ export_registration_pt export = arrayList_get(exports, i);
+ if (export != NULL) {
+ exportRegistration_stop(export);
+ exportRegistration_destroy(export);
+ }
+ }
+ arrayList_destroy(exports);
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+ int i;
+ int size = arrayList_size(admin->importedServices);
+ for (i = 0; i < size ; i += 1) {
+ import_registration_pt import = arrayList_get(admin->importedServices, i);
+ if (import != NULL) {
+ importRegistration_stop(import);
+ importRegistration_destroy(import);
+ }
+ }
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+ if (admin->ctx != NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Stopping webserver...");
+ mg_stop(admin->ctx);
+ admin->ctx = NULL;
+ }
+
+ hashMap_destroy(admin->exportedServices, false, false);
+ arrayList_destroy(admin->importedServices);
+
+ logHelper_stop(admin->loghelper);
+ logHelper_destroy(&admin->loghelper);
+
+ return status;
+}
+
+/**
+ * Request: http://host:port/services/{service}/{request}
+ */
+//void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) {
+
+celix_status_t importRegistration_getFactory(import_registration_pt import, service_factory_pt *factory);
+
+static int remoteServiceAdmin_callback(struct mg_connection *conn) {
+ int result = 1; // zero means: let civetweb handle it further, any non-zero value means it is handled by us...
+
+ const struct mg_request_info *request_info = mg_get_request_info(conn);
+ if (request_info->uri != NULL) {
+ remote_service_admin_pt rsa = request_info->user_data;
+
+
+ if (strncmp(request_info->uri, "/service/", 9) == 0 && strcmp("POST", request_info->request_method) == 0) {
+
+ // uri = /services/myservice/call
+ const char *uri = request_info->uri;
+ // rest = myservice/call
+
+ const char *rest = uri+9;
+ char *interfaceStart = strchr(rest, '/');
+ int pos = interfaceStart - rest;
+ char service[pos+1];
+ strncpy(service, rest, pos);
+ service[pos] = '\0';
+ unsigned long serviceId = strtoul(service,NULL,10);
+
+ celixThreadMutex_lock(&rsa->exportedServicesLock);
+
+ //find endpoint
+ export_registration_pt export = NULL;
+ hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ array_list_pt exports = hashMapEntry_getValue(entry);
+ int expIt = 0;
+ for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
+ export_registration_pt check = arrayList_get(exports, expIt);
+ export_reference_pt ref = NULL;
+ exportRegistration_getExportReference(check, &ref);
+ endpoint_description_pt checkEndpoint = NULL;
+ exportReference_getExportedEndpoint(ref, &checkEndpoint);
+ if (serviceId == checkEndpoint->serviceId) {
+ export = check;
+ free(ref);
+ break;
+ }
+ free(ref);
+ }
+ }
+ hashMapIterator_destroy(iter);
+
+ if (export != NULL) {
+
+ uint64_t datalength = request_info->content_length;
+ char* data = malloc(datalength + 1);
+ mg_read(conn, data, datalength);
+ data[datalength] = '\0';
+
+ char *response = NULL;
+ int responceLength = 0;
+ int rc = exportRegistration_call(export, data, -1, &response, &responceLength);
+ if (rc != CELIX_SUCCESS) {
+ RSA_LOG_ERROR(rsa, "Error trying to invoke remove service, got error %i\n", rc);
+ }
+
+ if (rc == CELIX_SUCCESS && response != NULL) {
+ mg_write(conn, data_response_headers, strlen(data_response_headers));
+ mg_write(conn, response, strlen(response));
+ free(response);
+ } else {
+ mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
+ }
+ result = 1;
+
+ free(data);
+ } else {
+ result = 0;
+ RSA_LOG_WARNING(rsa, "NO export registration found for service id %lu", serviceId);
+ }
+
+ celixThreadMutex_unlock(&rsa->exportedServicesLock);
+
+ }
+ }
+
+ return result;
+}
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations) {
+ celix_status_t status;
+
+ arrayList_create(registrations);
+ array_list_pt references = NULL;
+ service_reference_pt reference = NULL;
+ char filter [256];
+
+ snprintf(filter, 256, "(%s=%s)", (char *)OSGI_FRAMEWORK_SERVICE_ID, serviceId);
+
+ status = bundleContext_getServiceReferences(admin->context, NULL, filter, &references);
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: exportService called for serviceId %s", serviceId);
+
+ int i;
+ int size = arrayList_size(references);
+ for (i = 0; i < size; i += 1) {
+ if (i == 0) {
+ reference = arrayList_get(references, i);
+ } else {
+ bundleContext_ungetServiceReference(admin->context, arrayList_get(references, i));
+ }
+ }
+ arrayList_destroy(references);
+
+ if (reference == NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);
+ status = CELIX_ILLEGAL_STATE;
+ }
+
+ const char *exports = NULL;
+ const char *provided = NULL;
+ if (status == CELIX_SUCCESS) {
+ serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
+ serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_OBJECTCLASS, &provided);
+
+ if (exports == NULL || provided == NULL || strcmp(exports, provided) != 0) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No Services to export.");
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ const char *interface = provided;
+ endpoint_description_pt endpoint = NULL;
+ export_registration_pt registration = NULL;
+
+ remoteServiceAdmin_createEndpointDescription(admin, reference, properties, (char*)interface, &endpoint);
+ //TODO precheck if descriptor exists
+ status = exportRegistration_create(admin->loghelper, reference, endpoint, admin->context, ®istration);
+ if (status == CELIX_SUCCESS) {
+ status = exportRegistration_start(registration);
+ if (status == CELIX_SUCCESS) {
+ arrayList_add(*registrations, registration);
+ }
+ }
+ }
+
+
+ if (status == CELIX_SUCCESS) {
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+ hashMap_put(admin->exportedServices, reference, *registrations);
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+ }
+ else{
+ arrayList_destroy(*registrations);
+ *registrations = NULL;
+ }
+
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration) {
+ celix_status_t status;
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing exported service");
+
+ export_reference_pt ref = NULL;
+ status = exportRegistration_getExportReference(registration, &ref);
+
+ if (status == CELIX_SUCCESS && ref != NULL) {
+ service_reference_pt servRef;
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+ exportReference_getExportedService(ref, &servRef);
+
+ array_list_pt exports = (array_list_pt)hashMap_remove(admin->exportedServices, servRef);
+ if(exports!=NULL){
+ arrayList_destroy(exports);
+ }
+
+ exportRegistration_close(registration);
+ exportRegistration_destroy(registration);
+
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+ free(ref);
+
+ } else {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot find reference for registration");
+ }
+
+ return status;
+}
+
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, char *interface, endpoint_description_pt *endpoint) {
+
+ celix_status_t status = CELIX_SUCCESS;
+ properties_pt endpointProperties = properties_create();
+
+
+ unsigned int size = 0;
+ char **keys;
+
+ serviceReference_getPropertyKeys(reference, &keys, &size);
+ for (int i = 0; i < size; i++) {
+ char *key = keys[i];
+ const char *value = NULL;
+
+ if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS
+ && strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
+ && strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
+ properties_set(endpointProperties, key, value);
+ }
+ }
+
+ hash_map_entry_pt entry = hashMap_getEntry(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
+
+ char* key = hashMapEntry_getKey(entry);
+ char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
+ const char *uuid = NULL;
+
+ char buf[512];
+ snprintf(buf, 512, "/service/%s/%s", serviceId, interface);
+
+ char url[1024];
+ snprintf(url, 1024, "http://%s:%s%s", admin->ip, admin->port, buf);
+
+ uuid_t endpoint_uid;
+ uuid_generate(endpoint_uid);
+ char endpoint_uuid[37];
+ uuid_unparse_lower(endpoint_uid, endpoint_uuid);
+
+ bundleContext_getProperty(admin->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+ properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+ properties_set(endpointProperties, (char*) OSGI_FRAMEWORK_OBJECTCLASS, interface);
+ properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId);
+ properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, endpoint_uuid);
+ properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED, "true");
+ properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) CONFIGURATION_TYPE);
+ properties_set(endpointProperties, (char*) ENDPOINT_URL, url);
+
+ if (props != NULL) {
+ hash_map_iterator_pt propIter = hashMapIterator_create(props);
+ while (hashMapIterator_hasNext(propIter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(propIter);
+ properties_set(endpointProperties, (char*)hashMapEntry_getKey(entry), (char*)hashMapEntry_getValue(entry));
+ }
+ hashMapIterator_destroy(propIter);
+ }
+
+ *endpoint = calloc(1, sizeof(**endpoint));
+ if (!*endpoint) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*endpoint)->id = (char*)properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
+ const char *serviceId = NULL;
+ serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+ (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
+ (*endpoint)->frameworkUUID = (char*) properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+ (*endpoint)->service = strndup(interface, 1024*10);
+ (*endpoint)->properties = endpointProperties;
+ }
+
+ free(key);
+ free(serviceId);
+ free(keys);
+
+ return status;
+}
+
+static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip) {
+ celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+ struct ifaddrs *ifaddr, *ifa;
+ char host[NI_MAXHOST];
+
+ if (getifaddrs(&ifaddr) != -1)
+ {
+ for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr == NULL)
+ continue;
+
+ if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
+ if (interface == NULL) {
+ *ip = strdup(host);
+ status = CELIX_SUCCESS;
+ }
+ else if (strcmp(ifa->ifa_name, interface) == 0) {
+ *ip = strdup(host);
+ status = CELIX_SUCCESS;
+ }
+ }
+ }
+
+ freeifaddrs(ifaddr);
+ }
+
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description)
+{
+ celix_status_t status = CELIX_SUCCESS;
+
+ properties_destroy((*description)->properties);
+ free((*description)->service);
+ free(*description);
+
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpointDescription, import_registration_pt *out) {
+ celix_status_t status = CELIX_SUCCESS;
+ import_registration_pt import = NULL;
+
+ const char *objectClass = properties_get(endpointDescription->properties, "objectClass");
+ const char *serviceVersion = properties_get(endpointDescription->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION);
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "Registering service factory (proxy) for service '%s'\n", objectClass);
+
+ if (objectClass != NULL) {
+ status = importRegistration_create(admin->context, endpointDescription, objectClass, serviceVersion, &import);
+ }
+ if (status == CELIX_SUCCESS && import != NULL) {
+ importRegistration_setSendFn(import, (send_func_type) remoteServiceAdmin_send, admin);
+ }
+
+ if (status == CELIX_SUCCESS && import != NULL) {
+ status = importRegistration_start(import);
+ }
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+ arrayList_add(admin->importedServices, import);
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+ if (status == CELIX_SUCCESS) {
+ *out = import;
+ }
+
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing imported service");
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+ int i;
+ int size = arrayList_size(admin->importedServices);
+ import_registration_pt current = NULL;
+ for (i = 0; i < size; i += 1) {
+ current = arrayList_get(admin->importedServices, i);
+ if (current == registration) {
+ arrayList_remove(admin->importedServices, i);
+ importRegistration_close(current);
+ importRegistration_destroy(current);
+ break;
+ }
+ }
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+ return status;
+}
+
+
+static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
+ remote_service_admin_pt rsa = handle;
+ struct post post;
+ post.readptr = request;
+ post.size = strlen(request);
+
+ struct get get;
+ get.size = 0;
+ get.writeptr = malloc(1);
+
+ char *serviceUrl = (char*)properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
+ char url[256];
+ snprintf(url, 256, "%s", serviceUrl);
+
+ // assume the default timeout
+ int timeout = DEFAULT_TIMEOUT;
+
+ const char *timeoutStr = NULL;
+ // Check if the endpoint has a timeout, if so, use it.
+ timeoutStr = (char*) properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
+ if (timeoutStr == NULL) {
+ // If not, get the global variable and use that one.
+ bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
+ }
+
+ // Update timeout if a property is used to set it.
+ if (timeoutStr != NULL) {
+ timeout = atoi(timeoutStr);
+ }
+
+ celix_status_t status = CELIX_SUCCESS;
+ CURL *curl;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if(!curl) {
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_POST, 1L);
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
+ curl_easy_setopt(curl, CURLOPT_READDATA, &post);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
+ logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: Performing curl post\n");
+ res = curl_easy_perform(curl);
+
+ *reply = get.writeptr;
+ *replyStatus = res;
+
+ curl_easy_cleanup(curl);
+ }
+
+ return status;
+}
+
+static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp) {
+ struct post *post = userp;
+
+ if (post->size) {
+ *(char *) ptr = post->readptr[0];
+ post->readptr++;
+ post->size--;
+ return 1;
+ }
+
+ return 0;
+}
+
+static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp) {
+ size_t realsize = size * nmemb;
+ struct get *mem = (struct get *)userp;
+
+ mem->writeptr = realloc(mem->writeptr, mem->size + realsize + 1);
+ if (mem->writeptr == NULL) {
+ /* out of memory! */
+ printf("not enough memory (realloc returned NULL)");
+ exit(EXIT_FAILURE);
+ }
+
+ memcpy(&(mem->writeptr[mem->size]), contents, realsize);
+ mem->size += realsize;
+ mem->writeptr[mem->size] = 0;
+
+ return realsize;
+}
+
+
+static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...) {
+ va_list ap;
+ va_start(ap, msg);
+ int levels[5] = {0, OSGI_LOGSERVICE_ERROR, OSGI_LOGSERVICE_WARNING, OSGI_LOGSERVICE_INFO, OSGI_LOGSERVICE_DEBUG};
+
+ char buf1[256];
+ snprintf(buf1, 256, "FILE:%s, LINE:%i, MSG:", file, line);
+
+ char buf2[256];
+ vsnprintf(buf2, 256, msg, ap);
+ logHelper_log(admin->loghelper, levels[level], "%s%s", buf1, buf2);
+ va_end(ap);
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.h b/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.h
new file mode 100644
index 0000000..8b282f1
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.h
@@ -0,0 +1,57 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * remote_service_admin_http_impl.h
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
+#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
+
+
+#include "bundle_context.h"
+#include "endpoint_description.h"
+
+//typedef struct remote_service_admin *remote_service_admin_pt;
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
+celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration);
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
+
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
+celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service);
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
+celix_status_t importReference_getImportedService(import_reference_pt reference);
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
+
+#endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/test/CMakeLists.txt b/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
new file mode 100644
index 0000000..a78a6d0
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
@@ -0,0 +1,61 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+find_package(CppUTest REQUIRED)
+include_directories(${CPPUTEST_INCLUDE_DIR})
+
+add_bundle(rsa_dfi_tst_bundle
+ VERSION 0.0.1
+ SOURCES
+ src/tst_activator.c
+)
+get_target_property(DESCR calculator_api INTERFACE_CALCULATOR_DESCRIPTOR)
+bundle_files(rsa_dfi_tst_bundle ${DESCR} DESTINATION .)
+target_link_libraries(rsa_dfi_tst_bundle PRIVATE ${CPPUTEST_LIBRARY} calculator_api)
+target_include_directories(rsa_dfi_tst_bundle PRIVATE src)
+
+add_executable(test_rsa_dfi
+ src/run_tests.cpp
+ src/rsa_tests.cpp
+ src/rsa_client_server_tests.cpp
+)
+target_include_directories(test_rsa_dfi PRIVATE src)
+target_link_libraries(test_rsa_dfi PRIVATE ${CURL_LIBRARIES} ${CPPUTEST_LIBRARY}
+ Celix::framework
+ Celix::remote_service_admin_api
+ Celix::remote_service_admin_common
+ calculator_api)
+
+get_property(rsa_bundle_file TARGET remote_service_admin_dfi PROPERTY BUNDLE_FILE)
+get_property(calc_bundle_file TARGET calculator PROPERTY BUNDLE_FILE)
+get_property(calculator_shell_bundle_file TARGET calculator_shell PROPERTY BUNDLE_FILE)
+get_property(discovery_configured_bundle_file TARGET discovery_configured PROPERTY BUNDLE_FILE)
+get_property(topology_manager_bundle_file TARGET topology_manager PROPERTY BUNDLE_FILE)
+get_property(tst_bundle_file TARGET rsa_dfi_tst_bundle PROPERTY BUNDLE_FILE)
+
+configure_file(config.properties.in config.properties)
+configure_file(client.properties.in client.properties)
+configure_file(server.properties.in server.properties)
+
+add_dependencies(test_rsa_dfi
+ remote_service_admin_dfi_bundle #note depend on the target creating the bundle zip not the lib target
+ calculator_bundle
+)
+
+add_test(NAME run_test_rsa_dfi COMMAND test_rsa_dfi)
+SETUP_TARGET_FOR_COVERAGE(test_rsa_dfi_cov test_rsa_dfi ${CMAKE_BINARY_DIR}/coverage/test_rsa_dfi/test_rsa_dfi)
+
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/test/client.properties.in
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/test/client.properties.in b/remote_services/remote_service_admin_dfi/test/client.properties.in
new file mode 100644
index 0000000..a9a06fb
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/test/client.properties.in
@@ -0,0 +1,8 @@
+cosgi.auto.start.1=@rsa_bundle_file@ @calculator_shell_bundle_file@ @discovery_configured_bundle_file@ @topology_manager_bundle_file@ @tst_bundle_file@
+LOGHELPER_ENABLE_STDOUT_FALLBACK=true
+RSA_PORT=50881
+DISCOVERY_CFG_SERVER_PORT=50991
+DISCOVERY_CFG_POLL_ENDPOINTS=http://127.0.0.1:50992/org.apache.celix.discovery.configured
+org.osgi.framework.storage.clean=onFirstInit
+org.osgi.framework.storage=.cacheClient
+DISCOVERY_CFG_POLL_INTERVAL=1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/test/config.properties.in
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/test/config.properties.in b/remote_services/remote_service_admin_dfi/test/config.properties.in
new file mode 100644
index 0000000..5776ad8
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/test/config.properties.in
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+cosgi.auto.start.1=@rsa_bundle_file@ @calc_bundle_file@
+LOGHELPER_ENABLE_STDOUT_FALLBACK=true
+org.osgi.framework.storage.clean=onFirstInit
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/test/server.properties.in
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/test/server.properties.in b/remote_services/remote_service_admin_dfi/test/server.properties.in
new file mode 100644
index 0000000..707c7e6
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/test/server.properties.in
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+cosgi.auto.start.1=@rsa_bundle_file@ @calc_bundle_file@ @discovery_configured_bundle_file@ @topology_manager_bundle_file@
+LOGHELPER_ENABLE_STDOUT_FALLBACK=true
+RSA_PORT=50882
+DISCOVERY_CFG_SERVER_PORT=50992
+org.osgi.framework.storage.clean=onFirstInit
+org.osgi.framework.storage=.cacheServer
+DISCOVERY_CFG_POLL_INTERVAL=1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp b/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp
new file mode 100644
index 0000000..528e6b7
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp
@@ -0,0 +1,133 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <CppUTest/TestHarness.h>
+#include <remote_constants.h>
+#include <constants.h>
+#include <tst_service.h>
+#include "CppUTest/CommandLineTestRunner.h"
+#include "calculator_service.h"
+
+extern "C" {
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "celix_launcher.h"
+#include "framework.h"
+#include "remote_service_admin.h"
+#include "calculator_service.h"
+
+ static framework_pt serverFramework = NULL;
+ static bundle_context_pt serverContext = NULL;
+
+ static framework_pt clientFramework = NULL;
+ static bundle_context_pt clientContext = NULL;
+
+ static void setupFm(void) {
+ int rc = 0;
+ bundle_pt bundle = NULL;
+
+ //server
+ rc = celixLauncher_launch("server.properties", &serverFramework);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ bundle = NULL;
+ rc = framework_getFrameworkBundle(serverFramework, &bundle);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundle_getContext(bundle, &serverContext);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+
+ //client
+ rc = celixLauncher_launch("client.properties", &clientFramework);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ bundle = NULL;
+ rc = framework_getFrameworkBundle(clientFramework, &bundle);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundle_getContext(bundle, &clientContext);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ }
+
+ static void teardownFm(void) {
+ celixLauncher_stop(serverFramework);
+ celixLauncher_waitForShutdown(serverFramework);
+ celixLauncher_destroy(serverFramework);
+
+ celixLauncher_stop(clientFramework);
+ celixLauncher_waitForShutdown(clientFramework);
+ celixLauncher_destroy(clientFramework);
+
+ serverContext = NULL;
+ serverFramework = NULL;
+ clientContext = NULL;
+ clientFramework = NULL;
+ }
+
+ static void test1(void) {
+ celix_status_t rc;
+ service_reference_pt ref = NULL;
+ tst_service_pt tst = NULL;
+ int retries = 4;
+
+ while (ref == NULL && retries > 0) {
+ printf("Waiting for service .. %d\n", retries);
+ rc = bundleContext_getServiceReference(clientContext, (char *) TST_SERVICE_NAME, &ref);
+ usleep(1000000);
+ --retries;
+ }
+
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(ref != NULL);
+
+ rc = bundleContext_getService(clientContext, ref, (void **)&tst);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(tst != NULL);
+
+ rc = tst->test(tst->handle);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ bool result;
+ bundleContext_ungetService(clientContext, ref, &result);
+ bundleContext_ungetServiceReference(clientContext, ref);
+ }
+
+}
+
+
+TEST_GROUP(RsaDfiClientServerTests) {
+ void setup() {
+ setupFm();
+ }
+
+ void teardown() {
+ teardownFm();
+ }
+};
+
+TEST(RsaDfiClientServerTests, Test1) {
+ test1();
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp b/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp
new file mode 100644
index 0000000..6026ac6
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp
@@ -0,0 +1,234 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <CppUTest/TestHarness.h>
+#include <remote_constants.h>
+#include <constants.h>
+#include "CppUTest/CommandLineTestRunner.h"
+#include "calculator_service.h"
+
+extern "C" {
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "celix_launcher.h"
+#include "framework.h"
+#include "remote_service_admin.h"
+#include "calculator_service.h"
+
+
+ static framework_pt framework = NULL;
+ static bundle_context_pt context = NULL;
+
+ static service_reference_pt rsaRef = NULL;
+ static remote_service_admin_service_pt rsa = NULL;
+
+ static service_reference_pt calcRef = NULL;
+ static calculator_service_pt calc = NULL;
+
+ static void setupFm(void) {
+ int rc = 0;
+
+ rc = celixLauncher_launch("config.properties", &framework);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ bundle_pt bundle = NULL;
+ rc = framework_getFrameworkBundle(framework, &bundle);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundle_getContext(bundle, &context);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundleContext_getServiceReference(context, (char *)OSGI_RSA_REMOTE_SERVICE_ADMIN, &rsaRef);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(rsaRef != NULL);
+
+ rc = bundleContext_getService(context, rsaRef, (void **)&rsa);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundleContext_getServiceReference(context, (char *)CALCULATOR2_SERVICE, &calcRef);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(calcRef != NULL);
+
+ rc = bundleContext_getService(context, calcRef, (void **)&calc);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ }
+
+ static void teardownFm(void) {
+ int rc = 0;
+ rc = bundleContext_ungetService(context, rsaRef, NULL);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundleContext_ungetServiceReference(context, rsaRef);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundleContext_ungetService(context, calcRef, NULL);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundleContext_ungetServiceReference(context, calcRef);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ celixLauncher_stop(framework);
+ celixLauncher_waitForShutdown(framework);
+ celixLauncher_destroy(framework);
+
+ rsaRef = NULL;
+ rsa = NULL;
+ calcRef = NULL;
+ calc = NULL;
+ context = NULL;
+ framework = NULL;
+ }
+
+ static void testServices(void) {
+ int rc = 0;
+ array_list_pt exported = NULL;
+ array_list_pt imported = NULL;
+ arrayList_create(&exported);
+ arrayList_create(&imported);
+
+ rc = rsa->getExportedServices(rsa->admin, &exported);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK_EQUAL(0, arrayList_size(exported));
+
+ rc = rsa->getImportedEndpoints(rsa->admin, &imported);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK_EQUAL(0, arrayList_size(imported));
+
+ double result = 0;
+ rc = calc->add(calc->calculator, 2.0, 5.0, &result);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK_EQUAL(7.0, result);
+
+ arrayList_destroy(imported);
+ arrayList_destroy(exported);
+ }
+
+ static void testExportService(void) {
+ int rc = 0;
+ const char *calcId = NULL;
+ array_list_pt regs = NULL;
+
+ rc = serviceReference_getProperty(calcRef, (char *)"service.id", &calcId);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = rsa->exportService(rsa->admin, (char*)calcId, NULL, ®s);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ CHECK_EQUAL(1, arrayList_size(regs));
+
+ rc = rsa->exportRegistration_close(rsa->admin,(export_registration_pt)(arrayList_get(regs,0)));
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ }
+
+ static void testImportService(void) {
+ int rc = 0;
+ import_registration_pt reg = NULL;
+ endpoint_description_pt endpoint = NULL;
+
+ properties_pt props = properties_create();
+ properties_set(props, (char *)OSGI_RSA_ENDPOINT_SERVICE_ID, (char *)"42");
+ properties_set(props, (char *)OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, (char *)"eec5404d-51d0-47ef-8d86-c825a8beda42");
+ properties_set(props, (char *)OSGI_RSA_ENDPOINT_ID, (char *)"eec5404d-51d0-47ef-8d86-c825a8beda42-42");
+ properties_set(props, (char *)OSGI_FRAMEWORK_OBJECTCLASS,(char *)"org.apache.celix.Example");
+ properties_set(props, (char *)"service.version",(char *)"1.0.0"); //TODO find out standard in osgi spec
+
+ rc = endpointDescription_create(props, &endpoint);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = rsa->importService(rsa->admin, endpoint, ®);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(reg != NULL);
+
+ service_reference_pt ref = NULL;
+ rc = bundleContext_getServiceReference(context, (char *)"org.apache.celix.Example", &ref);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(ref != NULL);
+
+ rc = bundleContext_ungetServiceReference(context, ref);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = endpointDescription_destroy(endpoint);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ /* Cannot test. uses requesting bundles descriptor
+ void *service = NULL;
+ rc = bundleContext_getService(context, ref, &service);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(service != NULL);
+ */
+ }
+
+ static void testBundles(void) {
+ array_list_pt bundles = NULL;
+
+ int rc = bundleContext_getBundles(context, &bundles);
+ CHECK_EQUAL(0, rc);
+ CHECK_EQUAL(3, arrayList_size(bundles)); //framework, rsa_dfi & calc
+
+ /*
+ int size = arrayList_size(bundles);
+ int i;
+ for (i = 0; i < size; i += 1) {
+ bundle_pt bundle = NULL;
+ module_pt module = NULL;
+ char *name = NULL;
+
+ bundle = (bundle_pt) arrayList_get(bundles, i);
+ bundle_getCurrentModule(bundle, &module);
+ module_getSymbolicName(module, &name);
+ printf("got bundle with symbolic name '%s'", name);
+ }*/
+
+ arrayList_destroy(bundles);
+ }
+
+}
+
+
+TEST_GROUP(RsaDfiTests) {
+ void setup() {
+ setupFm();
+ }
+
+ void teardown() {
+ teardownFm();
+ }
+};
+
+TEST(RsaDfiTests, InfoTest) {
+ testServices();
+}
+
+TEST(RsaDfiTests, ExportService) {
+ testExportService();
+}
+
+TEST(RsaDfiTests, ImportService) {
+ testImportService();
+}
+
+TEST(RsaDfiTests, TestBundles) {
+ testBundles();
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp b/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp
new file mode 100644
index 0000000..b5fd502
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp
@@ -0,0 +1,25 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+int main(int argc, char** argv) {
+ return RUN_ALL_TESTS(argc, argv);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/test/src/tst_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/test/src/tst_activator.c b/remote_services/remote_service_admin_dfi/test/src/tst_activator.c
new file mode 100644
index 0000000..3db38fb
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/test/src/tst_activator.c
@@ -0,0 +1,162 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <service_tracker_customizer.h>
+#include <service_tracker.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+#include "service_reference.h"
+#include "celix_errno.h"
+
+#include "tst_service.h"
+#include "calculator_service.h"
+#include <unistd.h>
+
+
+struct activator {
+ bundle_context_pt context;
+ struct tst_service serv;
+ service_registration_pt reg;
+
+ service_tracker_customizer_pt cust;
+ service_tracker_pt tracker;
+ calculator_service_pt calc;
+};
+
+static celix_status_t addCalc(void * handle, service_reference_pt reference, void * service);
+static celix_status_t removeCalc(void * handle, service_reference_pt reference, void * service);
+static int test(void *handle);
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **out) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *act = calloc(1, sizeof(*act));
+ if (act != NULL) {
+ act->context = context;
+ act->serv.handle = act;
+ act->serv.test = test;
+
+ status = serviceTrackerCustomizer_create(act, NULL, addCalc, NULL, removeCalc, &act->cust);
+ status = CELIX_DO_IF(status, serviceTracker_create(context, CALCULATOR2_SERVICE, act->cust, &act->tracker));
+
+ } else {
+ status = CELIX_ENOMEM;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ *out = act;
+ } else if (act != NULL) {
+ if (act->cust != NULL) {
+ free(act->cust);
+ act->cust = NULL;
+ }
+ if (act->tracker != NULL) {
+ serviceTracker_destroy(act->tracker);
+ act->tracker = NULL;
+ }
+ free(act);
+ }
+
+ return CELIX_SUCCESS;
+}
+
+static celix_status_t addCalc(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator * act = handle;
+ act->calc = service;
+ return status;
+}
+
+static celix_status_t removeCalc(void * handle, service_reference_pt reference, void * service) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator * act = handle;
+ if (act->calc == service) {
+ act->calc = NULL;
+ }
+ return status;
+
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator * act = userData;
+
+ act->reg = NULL;
+ status = bundleContext_registerService(context, (char *)TST_SERVICE_NAME, &act->serv, NULL, &act->reg);
+
+ status = CELIX_DO_IF(status, serviceTracker_open(act->tracker));
+
+
+ return status;
+}
+
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator * act = userData;
+
+ status = serviceRegistration_unregister(act->reg);
+ status = CELIX_DO_IF(status, serviceTracker_close(act->tracker));
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ struct activator *act = userData;
+ if (act != NULL) {
+ if (act->tracker != NULL) {
+ serviceTracker_destroy(act->tracker);
+ act->tracker = NULL;
+ }
+ free(act);
+ }
+ return CELIX_SUCCESS;
+}
+
+static int test(void *handle) {
+ int status = 0;
+ struct activator *act = handle;
+
+ double result = -1.0;
+
+ int retries = 40;
+
+ while (act->calc == NULL) {
+ printf("Waiting for calc service .. %d\n", retries);
+ usleep(100000);
+ --retries;
+ }
+
+ int rc = 1;
+ if (act->calc != NULL) {
+ rc = act->calc->sqrt(act->calc->calculator, 4, &result);
+ printf("calc result is %f\n", result);
+ } else {
+ printf("calc not ready\n");
+ }
+
+ if (rc != 0 || result != 2.0) {
+ status = 1;
+ }
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/test/src/tst_service.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/test/src/tst_service.h b/remote_services/remote_service_admin_dfi/test/src/tst_service.h
new file mode 100644
index 0000000..c8ca2e7
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/test/src/tst_service.h
@@ -0,0 +1,32 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef CELIX_TST_SERVICE_H
+#define CELIX_TST_SERVICE_H
+
+#define TST_SERVICE_NAME "tst_service"
+
+struct tst_service {
+ void *handle;
+ int (*test)(void *handle);
+};
+
+typedef struct tst_service *tst_service_pt;
+
+#endif //CELIX_TST_SERVICE_H
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/topology_manager/src/topology_manager.h
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/src/topology_manager.h b/remote_services/topology_manager/src/topology_manager.h
index 7e5e917..b6ee064 100644
--- a/remote_services/topology_manager/src/topology_manager.h
+++ b/remote_services/topology_manager/src/topology_manager.h
@@ -35,6 +35,7 @@
#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin"
+typedef struct topology_manager topology_manager_t;
typedef struct topology_manager *topology_manager_pt;
celix_status_t topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, topology_manager_pt *manager, void **scope);
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/topology_manager/tms_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/CMakeLists.txt b/remote_services/topology_manager/tms_tst/CMakeLists.txt
index 6d0713c..5e27139 100644
--- a/remote_services/topology_manager/tms_tst/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/CMakeLists.txt
@@ -37,9 +37,18 @@ add_executable(test_tm_scoped
run_tests.cpp
tms_tests.cpp
)
-target_link_libraries(test_tm_scoped Celix::framework ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY} Celix::log_helper remote_service_admin_common)
+target_include_directories(test_tm_scoped PRIVATE ../src ../include)
+target_link_libraries(test_tm_scoped PRIVATE
+ Celix::framework
+ ${CPPUTEST_LIBRARY}
+ ${JANSSON_LIBRARY}
+ Celix::log_helper
+ calculator_api
+ Celix::remote_service_admin_api
+ Celix::remote_service_admin_common
+)
-add_dependencies(test_tm_scoped remote_service_admin_dfi topology_manager calculator)
+add_dependencies(test_tm_scoped remote_service_admin_dfi_bundle topology_manager_bundle)
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config.properties"
@@ -57,13 +66,6 @@ LOGHELPER_ENABLE_STDOUT_FALLBACK=true
org.osgi.framework.storage.clean=onFirstInit
")
-
-#TODO improve copy commands, for now using configure_file as copy
-#add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scope.json" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURE_DIR}/scope.json" "${CMAKE_CURRENT_BINARY_DIR}/scope.json")
-#add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scope2.json" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURE_DIR}/scope2.json" "${CMAKE_CURRENT_BINARY_DIR}/scope2.json")
-#add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scope3.json" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURE_DIR}/scope3.json" "${CMAKE_CURRENT_BINARY_DIR}/scope3.json")
-#add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scope4.json" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURE_DIR}/scope4.json" "${CMAKE_CURRENT_BINARY_DIR}/scope4.json")
-
configure_file("scope.json" "scope.json")
configure_file("scope2.json" "scope2.json")
configure_file("scope3.json" "scope3.json")
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
index fc9d9bf..551995b 100644
--- a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
@@ -32,4 +32,4 @@ bundle_files(topology_manager_test_bundle
DESTINATION .
)
-target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY} remote_service_admin calculator_api)
+target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::remote_service_admin_api calculator_api)
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt b/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
index bfd7fc1..653b69c 100644
--- a/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
@@ -20,7 +20,9 @@ add_bundle(topology_manager_disc_mock_bundle
SOURCES
disc_mock_activator.c
disc_mock_service.c
-
)
-target_include_directories(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_INCLUDE_DIR})
-target_link_libraries(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::framework discovery_common)
+target_include_directories(topology_manager_disc_mock_bundle PRIVATE
+ ${CPPUTEST_INCLUDE_DIR}
+ $<TARGET_PROPERTY:discovery_common,INCLUDE_DIRECTORIES>
+)
+target_link_libraries(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::framework)
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c b/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c
index 53fccd7..d07ce02 100644
--- a/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c
+++ b/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c
@@ -29,7 +29,6 @@
#include "celix_errno.h"
#include "disc_mock_service.h"
-#include "discovery.h"
#include "constants.h"
#include "remote_constants.h"
[7/8] celix git commit: CELIX-417: Refactors CMake usage for the RSA
bundles
Posted by pn...@apache.org.
CELIX-417: Refactors CMake usage for the RSA bundles
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/27a2aa75
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/27a2aa75
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/27a2aa75
Branch: refs/heads/feature/CELIX-417-cmake-refactor
Commit: 27a2aa756025018dd2406cc5b423d2ff5e38cf87
Parents: 2a670f2
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Nov 24 11:38:49 2017 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Nov 24 11:38:49 2017 +0100
----------------------------------------------------------------------
cmake/cmake_celix/BundlePackaging.cmake | 6 +-
cmake/cmake_celix/DeployPackaging.cmake | 2 +-
dfi/CMakeLists.txt | 41 +-
framework/src/bundle_context.c | 2 +-
log_service/loghelper_include/log_helper.h | 1 +
log_writer/CMakeLists.txt | 2 +-
remote_services/CMakeLists.txt | 2 +
remote_services/civetweb/CMakeLists.txt | 23 +
remote_services/civetweb/include/civetweb.h | 657 ++
remote_services/civetweb/src/civetweb.c | 7907 ++++++++++++++++++
remote_services/civetweb/src/md5.inl | 461 +
remote_services/discovery_common/CMakeLists.txt | 18 +-
.../discovery_common/include/civetweb.h | 657 --
.../discovery_common/include/discovery.h | 23 +-
.../discovery_common/include/discovery_type.h | 27 +
.../include/endpoint_discovery_poller.h | 9 +-
.../include/endpoint_discovery_server.h | 11 +-
remote_services/discovery_common/src/civetweb.c | 7907 ------------------
.../discovery_common/src/discovery.c | 1 -
.../src/endpoint_discovery_poller.c | 7 +-
.../src/endpoint_discovery_server.c | 20 +-
remote_services/discovery_common/src/md5.inl | 461 -
.../discovery_configured/CMakeLists.txt | 10 +-
.../discovery_configured/src/discovery_impl.c | 4 +-
.../discovery_configured/src/discovery_impl.h | 28 +-
remote_services/discovery_etcd/CMakeLists.txt | 16 +-
.../discovery_etcd/src/discovery_impl.c | 44 +-
.../discovery_etcd/src/discovery_impl.h | 16 +-
.../discovery_etcd/src/etcd_watcher.h | 1 +
remote_services/discovery_shm/CMakeLists.txt | 6 +-
.../discovery_shm/src/discovery_impl.c | 42 +-
.../discovery_shm/src/discovery_impl.h | 21 +-
.../discovery_shm/src/discovery_shmWatcher.c | 19 +-
.../discovery_shm/src/discovery_shmWatcher.h | 1 +
.../remote_service_admin_common/CMakeLists.txt | 4 +-
.../remote_service_admin_dfi/CMakeLists.txt | 32 +-
.../remote_service_admin_dfi/rsa/CMakeLists.txt | 34 -
.../rsa/src/dfi_utils.c | 98 -
.../rsa/src/dfi_utils.h | 30 -
.../rsa/src/export_registration_dfi.c | 251 -
.../rsa/src/export_registration_dfi.h | 38 -
.../rsa/src/import_registration_dfi.c | 402 -
.../rsa/src/import_registration_dfi.h | 44 -
.../rsa/src/remote_service_admin_activator.c | 124 -
.../rsa/src/remote_service_admin_dfi.c | 775 --
.../rsa/src/remote_service_admin_dfi.h | 57 -
.../rsa_tst/CMakeLists.txt | 52 -
.../rsa_tst/bundle/CMakeLists.txt | 29 -
.../rsa_tst/bundle/tst_activator.c | 153 -
.../rsa_tst/bundle/tst_service.h | 32 -
.../rsa_tst/client.properties.in | 8 -
.../rsa_tst/config.properties.in | 20 -
.../rsa_tst/rsa_client_server_tests.cpp | 133 -
.../rsa_tst/rsa_tests.cpp | 234 -
.../rsa_tst/run_tests.cpp | 25 -
.../rsa_tst/server.properties.in | 23 -
.../remote_service_admin_dfi/src/dfi_utils.c | 108 +
.../remote_service_admin_dfi/src/dfi_utils.h | 30 +
.../src/export_registration_dfi.c | 251 +
.../src/export_registration_dfi.h | 38 +
.../src/import_registration_dfi.c | 402 +
.../src/import_registration_dfi.h | 44 +
.../src/remote_service_admin_activator.c | 124 +
.../src/remote_service_admin_dfi.c | 771 ++
.../src/remote_service_admin_dfi.h | 57 +
.../test/CMakeLists.txt | 61 +
.../test/client.properties.in | 8 +
.../test/config.properties.in | 20 +
.../test/server.properties.in | 23 +
.../test/src/rsa_client_server_tests.cpp | 133 +
.../test/src/rsa_tests.cpp | 234 +
.../test/src/run_tests.cpp | 25 +
.../test/src/tst_activator.c | 162 +
.../test/src/tst_service.h | 32 +
.../topology_manager/src/topology_manager.h | 1 +
.../topology_manager/tms_tst/CMakeLists.txt | 20 +-
.../tms_tst/bundle/CMakeLists.txt | 2 +-
.../tms_tst/disc_mock/CMakeLists.txt | 8 +-
.../tms_tst/disc_mock/disc_mock_activator.c | 1 -
79 files changed, 11847 insertions(+), 11759 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/cmake/cmake_celix/BundlePackaging.cmake
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/BundlePackaging.cmake b/cmake/cmake_celix/BundlePackaging.cmake
index c5d75d6..205bec1 100644
--- a/cmake/cmake_celix/BundlePackaging.cmake
+++ b/cmake/cmake_celix/BundlePackaging.cmake
@@ -145,14 +145,14 @@ function(add_bundle)
set_library_version(${BUNDLE_TARGET_NAME} ${BUNDLE_VERSION})
set_target_properties(${BUNDLE_TARGET_NAME} PROPERTIES
"BUNDLE_TARGET_IS_LIB" TRUE
- "BUNDLE_BUILD_BUNDLE_TARGET" "${BUNDLE_TARGET_NAME}_bundle"
+ "BUNDLE_TARGET" "${BUNDLE_TARGET_NAME}_bundle"
)
target_link_libraries(${BUNDLE_TARGET_NAME} PRIVATE Celix::framework)
else()
add_custom_target(${BUNDLE_TARGET_NAME})
set_target_properties(${BUNDLE_TARGET_NAME} PROPERTIES
"BUNDLE_TARGET_IS_LIB" FALSE
- "BUNDLE_BUILD_BUNDLE_TARGET" "${BUNDLE_TARGET_NAME}_bundle"
+ "BUNDLE_TARGET" "${BUNDLE_TARGET_NAME}_bundle"
)
endif()
add_custom_target(${BUNDLE_TARGET_NAME}_bundle
@@ -213,7 +213,7 @@ function(add_bundle)
#############################
#alreadyer set
# BUNDLE_TARGET_IS_LIB -> true (can be use to test if target is bundle target
- # BUNDLE_BUILD_BUNDLE_TARGET -> refers to the _bundle target which is responsible for building the zip file
+ # BUNDLE_TARGET -> refers to the _bundle target which is responsible for building the zip file
#internal use
set_target_properties(${BUNDLE_TARGET_NAME} PROPERTIES "BUNDLE_IS_BUNDLE_TARGET" TRUE) #indicate that this is a bundle target
set_target_properties(${BUNDLE_TARGET_NAME} PROPERTIES "BUNDLE_DEPEND_TARGETS" "") #bundle target dependencies. Note can be extended after the add_bundle call
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/cmake/cmake_celix/DeployPackaging.cmake
----------------------------------------------------------------------
diff --git a/cmake/cmake_celix/DeployPackaging.cmake b/cmake/cmake_celix/DeployPackaging.cmake
index e7f8dc6..dfef9dd 100644
--- a/cmake/cmake_celix/DeployPackaging.cmake
+++ b/cmake/cmake_celix/DeployPackaging.cmake
@@ -227,7 +227,7 @@ function(celix_container_bundles_dir)
COMMENT "Copying bundle '${BUNDLE}' to '${CONTAINER_LOC}/${BD_DIR_NAME}'"
DEPENDS $<TARGET_PROPERTY:${BUNDLE},BUNDLE_BUILD_BUNDLE_TARGET>
)
- get_target_property(BUILD_BUNDLE_TARGET ${BUNDLE} BUNDLE_BUILD_BUNDLE_TARGET)
+ get_target_property(BUILD_BUNDLE_TARGET ${BUNDLE} BUNDLE_TARGET)
add_dependencies(${CONTAINER_TARGET} ${BUILD_BUNDLE_TARGET}) #ensure the the deploy depends on the _bundle target, custom_command depends on add_library
endif()
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/dfi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/dfi/CMakeLists.txt b/dfi/CMakeLists.txt
index ad3a41f..642ac68 100644
--- a/dfi/CMakeLists.txt
+++ b/dfi/CMakeLists.txt
@@ -18,36 +18,37 @@
find_package(FFI REQUIRED)
find_package(Jansson REQUIRED)
-add_library(dfi SHARED
- src/dyn_common.c
- src/dyn_type.c
- src/dyn_function.c
- src/dyn_interface.c
- src/dyn_message.c
- src/json_serializer.c
- src/json_rpc.c
-)
-set_target_properties(dfi PROPERTIES OUTPUT_NAME "celix_dfi")
-
-target_include_directories(dfi PUBLIC
- include
- ${JANSSON_INCLUDE_DIRS}
-)
-target_include_directories(dfi PRIVATE
- src
- ${FFI_INCLUDE_DIRS}
+set(SOURCES
+ src/dyn_common.c
+ src/dyn_type.c
+ src/dyn_function.c
+ src/dyn_interface.c
+ src/dyn_message.c
+ src/json_serializer.c
+ src/json_rpc.c
)
+add_library(dfi SHARED ${SOURCES})
+set_target_properties(dfi PROPERTIES OUTPUT_NAME "celix_dfi")
+target_include_directories(dfi PUBLIC include ${JANSSON_INCLUDE_DIRS})
+target_include_directories(dfi PRIVATE src ${FFI_INCLUDE_DIRS})
target_link_libraries(dfi PUBLIC ${JANSSON_LIBRARY})
target_link_libraries(dfi PRIVATE Celix::utils ${FFI_LIBRARIES})
-
set_target_properties(dfi PROPERTIES "SOVERSION" 1)
-install(TARGETS dfi DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT framework)
+add_library(dfi_static STATIC ${SOURCES})
+set_target_properties(dfi_static PROPERTIES OUTPUT_NAME "celix_dfi_static")
+target_include_directories(dfi_static PUBLIC include ${JANSSON_INCLUDE_DIRS})
+target_include_directories(dfi_static PRIVATE src ${FFI_INCLUDE_DIRS})
+target_link_libraries(dfi_static PUBLIC ${JANSSON_LIBRARY})
+target_link_libraries(dfi_static PRIVATE Celix::utils ${FFI_LIBRARIES})
+
+install(TARGETS dfi dfi_static DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT framework)
#Alias setup to match external usage
add_library(Celix::dfi ALIAS dfi)
+add_library(Celix::dfi_static ALIAS dfi_static)
if (ENABLE_TESTING)
find_package(CppUTest REQUIRED)
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/framework/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context.c b/framework/src/bundle_context.c
index face85d..928a7a4 100644
--- a/framework/src/bundle_context.c
+++ b/framework/src/bundle_context.c
@@ -222,7 +222,7 @@ celix_status_t bundleContext_ungetServiceReference(bundle_context_pt context, se
celix_status_t bundleContext_getService(bundle_context_pt context, service_reference_pt reference, void** service_instance) {
celix_status_t status = CELIX_SUCCESS;
- if (context != NULL && reference != NULL && *service_instance == NULL) {
+ if (context != NULL && reference != NULL && service_instance != NULL) {
/*NOTE argument service_instance should be considerd a 'const void**'.
To ensure backwards compatiblity a cast is made instead.
*/
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/log_service/loghelper_include/log_helper.h
----------------------------------------------------------------------
diff --git a/log_service/loghelper_include/log_helper.h b/log_service/loghelper_include/log_helper.h
index 04e4bb2..2ae9d83 100644
--- a/log_service/loghelper_include/log_helper.h
+++ b/log_service/loghelper_include/log_helper.h
@@ -24,6 +24,7 @@
#include "bundle_context.h"
#include "log_service.h"
+typedef struct log_helper log_helper_t;
typedef struct log_helper* log_helper_pt;
celix_status_t logHelper_create(bundle_context_pt context, log_helper_pt* log_helper);
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/log_writer/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/log_writer/CMakeLists.txt b/log_writer/CMakeLists.txt
index 340af15..e44ef65 100644
--- a/log_writer/CMakeLists.txt
+++ b/log_writer/CMakeLists.txt
@@ -23,5 +23,5 @@ if (LOG_WRITER)
#Setup target aliases to match external usage
add_library(Celix::log_writer_stdout ALIAS log_writer_stdout)
- add_library(Celix::log_writer_syslog ALIAS log_writer_syslog)
+ #add_library(Celix::log_writer_syslog ALIAS log_writer_syslog)
endif (LOG_WRITER)
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/CMakeLists.txt b/remote_services/CMakeLists.txt
index 7ca1c44..4e1f5b3 100644
--- a/remote_services/CMakeLists.txt
+++ b/remote_services/CMakeLists.txt
@@ -22,6 +22,8 @@ if (REMOTE_SERVICE_ADMIN)
add_subdirectory(topology_manager)
+ add_subdirectory(civetweb)
+
add_subdirectory(discovery_common)
add_subdirectory(discovery_configured)
add_subdirectory(discovery_etcd)
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/civetweb/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/civetweb/CMakeLists.txt b/remote_services/civetweb/CMakeLists.txt
new file mode 100644
index 0000000..e9e272e
--- /dev/null
+++ b/remote_services/civetweb/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+add_library(civetweb OBJECT
+ src/civetweb.c
+ src/md5.inl
+)
+target_include_directories(civetweb PUBLIC include)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/civetweb/include/civetweb.h
----------------------------------------------------------------------
diff --git a/remote_services/civetweb/include/civetweb.h b/remote_services/civetweb/include/civetweb.h
new file mode 100644
index 0000000..61a8e98
--- /dev/null
+++ b/remote_services/civetweb/include/civetweb.h
@@ -0,0 +1,657 @@
+/* Copyright (c) 2013-2014 the Civetweb developers
+ * Copyright (c) 2004-2013 Sergey Lyubka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef CIVETWEB_HEADER_INCLUDED
+#define CIVETWEB_HEADER_INCLUDED
+
+#ifndef CIVETWEB_VERSION
+#define CIVETWEB_VERSION "1.7"
+#endif
+
+#ifndef CIVETWEB_API
+ #if defined(_WIN32)
+ #if defined(CIVETWEB_DLL_EXPORTS)
+ #define CIVETWEB_API __declspec(dllexport)
+ #elif defined(CIVETWEB_DLL_IMPORTS)
+ #define CIVETWEB_API __declspec(dllimport)
+ #else
+ #define CIVETWEB_API
+ #endif
+ #else
+ #define CIVETWEB_API
+ #endif
+#endif
+
+#include <stdio.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct mg_context; /* Handle for the HTTP service itself */
+struct mg_connection; /* Handle for the individual connection */
+
+
+/* This structure contains information about the HTTP request. */
+struct mg_request_info {
+ const char *request_method; /* "GET", "POST", etc */
+ const char *uri; /* URL-decoded URI */
+ const char *http_version; /* E.g. "1.0", "1.1" */
+ const char *query_string; /* URL part after '?', not including '?', or
+ NULL */
+ const char *remote_user; /* Authenticated user, or NULL if no auth
+ used */
+ char remote_addr[48]; /* Client's IP address as a string. */
+ long remote_ip; /* Client's IP address. Deprecated: use remote_addr instead */
+
+ long long content_length; /* Length (in bytes) of the request body,
+ can be -1 if no length was given. */
+ int remote_port; /* Client's port */
+ int is_ssl; /* 1 if SSL-ed, 0 if not */
+ void *user_data; /* User data pointer passed to mg_start() */
+ void *conn_data; /* Connection-specific user data */
+
+ int num_headers; /* Number of HTTP headers */
+ struct mg_header {
+ const char *name; /* HTTP header name */
+ const char *value; /* HTTP header value */
+ } http_headers[64]; /* Maximum 64 headers */
+};
+
+
+/* This structure needs to be passed to mg_start(), to let civetweb know
+ which callbacks to invoke. For a detailed description, see
+ https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md */
+struct mg_callbacks {
+ /* Called when civetweb has received new HTTP request.
+ If the callback returns one, it must process the request
+ by sending valid HTTP headers and a body. Civetweb will not do
+ any further processing. Otherwise it must return zero.
+ Note that since V1.7 the "begin_request" function is called
+ before an authorization check. If an authorization check is
+ required, use a request_handler instead.
+ Return value:
+ 0: civetweb will process the request itself. In this case,
+ the callback must not send any data to the client.
+ 1: callback already processed the request. Civetweb will
+ not send any data after the callback returned. */
+ int (*begin_request)(struct mg_connection *);
+
+ /* Called when civetweb has finished processing request. */
+ void (*end_request)(const struct mg_connection *, int reply_status_code);
+
+ /* Called when civetweb is about to log a message. If callback returns
+ non-zero, civetweb does not log anything. */
+ int (*log_message)(const struct mg_connection *, const char *message);
+
+ /* Called when civetweb initializes SSL library.
+ Parameters:
+ user_data: parameter user_data passed when starting the server.
+ Return value:
+ 0: civetweb will set up the SSL certificate.
+ 1: civetweb assumes the callback already set up the certificate.
+ -1: initializing ssl fails. */
+ int (*init_ssl)(void *ssl_context, void *user_data);
+
+ /* Called when websocket request is received, before websocket handshake.
+ Return value:
+ 0: civetweb proceeds with websocket handshake.
+ 1: connection is closed immediately. */
+ int (*websocket_connect)(const struct mg_connection *);
+
+ /* Called when websocket handshake is successfully completed, and
+ connection is ready for data exchange. */
+ void (*websocket_ready)(struct mg_connection *);
+
+ /* Called when data frame has been received from the client.
+ Parameters:
+ bits: first byte of the websocket frame, see websocket RFC at
+ http://tools.ietf.org/html/rfc6455, section 5.2
+ data, data_len: payload, with mask (if any) already applied.
+ Return value:
+ 1: keep this websocket connection open.
+ 0: close this websocket connection. */
+ int (*websocket_data)(struct mg_connection *, int bits,
+ char *data, size_t data_len);
+
+ /* Called when civetweb is closing a connection. The per-context mutex is
+ locked when this is invoked. This is primarily useful for noting when
+ a websocket is closing and removing it from any application-maintained
+ list of clients. */
+ void (*connection_close)(struct mg_connection *);
+
+ /* Called when civetweb tries to open a file. Used to intercept file open
+ calls, and serve file data from memory instead.
+ Parameters:
+ path: Full path to the file to open.
+ data_len: Placeholder for the file size, if file is served from
+ memory.
+ Return value:
+ NULL: do not serve file from memory, proceed with normal file open.
+ non-NULL: pointer to the file contents in memory. data_len must be
+ initilized with the size of the memory block. */
+ const char * (*open_file)(const struct mg_connection *,
+ const char *path, size_t *data_len);
+
+ /* Called when civetweb is about to serve Lua server page, if
+ Lua support is enabled.
+ Parameters:
+ lua_context: "lua_State *" pointer. */
+ void (*init_lua)(struct mg_connection *, void *lua_context);
+
+ /* Called when civetweb has uploaded a file to a temporary directory as a
+ result of mg_upload() call.
+ Parameters:
+ file_name: full path name to the uploaded file. */
+ void (*upload)(struct mg_connection *, const char *file_name);
+
+ /* Called when civetweb is about to send HTTP error to the client.
+ Implementing this callback allows to create custom error pages.
+ Parameters:
+ status: HTTP error status code.
+ Return value:
+ 1: run civetweb error handler.
+ 0: callback already handled the error. */
+ int (*http_error)(struct mg_connection *, int status);
+
+ /* Called after civetweb context has been created, before requests
+ are processed.
+ Parameters:
+ ctx: context handle */
+ void (*init_context)(struct mg_context * ctx);
+
+ /* Called when civetweb context is deleted.
+ Parameters:
+ ctx: context handle */
+ void (*exit_context)(struct mg_context * ctx);
+};
+
+
+/* Start web server.
+
+ Parameters:
+ callbacks: mg_callbacks structure with user-defined callbacks.
+ options: NULL terminated list of option_name, option_value pairs that
+ specify Civetweb configuration parameters.
+
+ Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
+ processing is required for these, signal handlers must be set up
+ after calling mg_start().
+
+
+ Example:
+ const char *options[] = {
+ "document_root", "/var/www",
+ "listening_ports", "80,443s",
+ NULL
+ };
+ struct mg_context *ctx = mg_start(&my_func, NULL, options);
+
+ Refer to https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md
+ for the list of valid option and their possible values.
+
+ Return:
+ web server context, or NULL on error. */
+CIVETWEB_API struct mg_context *mg_start(const struct mg_callbacks *callbacks,
+ void *user_data,
+ const char **configuration_options);
+
+
+/* Stop the web server.
+
+ Must be called last, when an application wants to stop the web server and
+ release all associated resources. This function blocks until all Civetweb
+ threads are stopped. Context pointer becomes invalid. */
+CIVETWEB_API void mg_stop(struct mg_context *);
+
+
+/* mg_request_handler
+
+ Called when a new request comes in. This callback is URI based
+ and configured with mg_set_request_handler().
+
+ Parameters:
+ conn: current connection information.
+ cbdata: the callback data configured with mg_set_request_handler().
+ Returns:
+ 0: the handler could not handle the request, so fall through.
+ 1: the handler processed the request. */
+typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata);
+
+
+/* mg_set_request_handler
+
+ Sets or removes a URI mapping for a request handler.
+
+ URI's are ordered and prefixed URI's are supported. For example,
+ consider two URIs: /a/b and /a
+ /a matches /a
+ /a/b matches /a/b
+ /a/c matches /a
+
+ Parameters:
+ ctx: server context
+ uri: the URI to configure
+ handler: the callback handler to use when the URI is requested.
+ If NULL, the URI will be removed.
+ cbdata: the callback data to give to the handler when it s requested. */
+CIVETWEB_API void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata);
+
+
+/* Get the value of particular configuration parameter.
+ The value returned is read-only. Civetweb does not allow changing
+ configuration at run time.
+ If given parameter name is not valid, NULL is returned. For valid
+ names, return value is guaranteed to be non-NULL. If parameter is not
+ set, zero-length string is returned. */
+CIVETWEB_API const char *mg_get_option(const struct mg_context *ctx, const char *name);
+
+
+/* Get context from connection. */
+CIVETWEB_API struct mg_context *mg_get_context(struct mg_connection *conn);
+
+
+/* Get user data passed to mg_start from context. */
+CIVETWEB_API void *mg_get_user_data(struct mg_context *ctx);
+
+
+#if defined(MG_LEGACY_INTERFACE)
+/* Return array of strings that represent valid configuration options.
+ For each option, option name and default value is returned, i.e. the
+ number of entries in the array equals to number_of_options x 2.
+ Array is NULL terminated. */
+/* Deprecated: Use mg_get_valid_options instead. */
+CIVETWEB_API const char **mg_get_valid_option_names(void);
+#endif
+
+
+struct mg_option {
+ const char * name;
+ int type;
+ const char * default_value;
+};
+
+enum {
+ CONFIG_TYPE_UNKNOWN = 0x0,
+ CONFIG_TYPE_NUMBER = 0x1,
+ CONFIG_TYPE_STRING = 0x2,
+ CONFIG_TYPE_FILE = 0x3,
+ CONFIG_TYPE_DIRECTORY = 0x4,
+ CONFIG_TYPE_BOOLEAN = 0x5,
+ CONFIG_TYPE_EXT_PATTERN = 0x6
+};
+
+
+/* Return array of struct mg_option, representing all valid configuration
+ options of civetweb.c.
+ The array is terminated by a NULL name option. */
+CIVETWEB_API const struct mg_option *mg_get_valid_options(void);
+
+
+/* Get the list of ports that civetweb is listening on.
+ size is the size of the ports int array and ssl int array to fill.
+ It is the caller's responsibility to make sure ports and ssl each
+ contain at least size int elements worth of memory to write into.
+ Return value is the number of ports and ssl information filled in.
+ The value returned is read-only. Civetweb does not allow changing
+ configuration at run time. */
+CIVETWEB_API size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl);
+
+
+/* Add, edit or delete the entry in the passwords file.
+
+ This function allows an application to manipulate .htpasswd files on the
+ fly by adding, deleting and changing user records. This is one of the
+ several ways of implementing authentication on the server side. For another,
+ cookie-based way please refer to the examples/chat in the source tree.
+
+ If password is not NULL, entry is added (or modified if already exists).
+ If password is NULL, entry is deleted.
+
+ Return:
+ 1 on success, 0 on error. */
+CIVETWEB_API int mg_modify_passwords_file(const char *passwords_file_name,
+ const char *domain,
+ const char *user,
+ const char *password);
+
+
+/* Return information associated with the request. */
+CIVETWEB_API struct mg_request_info *mg_get_request_info(struct mg_connection *);
+
+
+/* Send data to the client.
+ Return:
+ 0 when the connection has been closed
+ -1 on error
+ >0 number of bytes written on success */
+CIVETWEB_API int mg_write(struct mg_connection *, const void *buf, size_t len);
+
+
+/* Send data to a websocket client wrapped in a websocket frame. Uses mg_lock
+ to ensure that the transmission is not interrupted, i.e., when the
+ application is proactively communicating and responding to a request
+ simultaneously.
+
+ Send data to a websocket client wrapped in a websocket frame.
+ This function is available when civetweb is compiled with -DUSE_WEBSOCKET
+
+ Return:
+ 0 when the connection has been closed
+ -1 on error
+ >0 number of bytes written on success */
+CIVETWEB_API int mg_websocket_write(struct mg_connection* conn, int opcode,
+ const char *data, size_t data_len);
+
+
+/* Blocks until unique access is obtained to this connection. Intended for use
+ with websockets only.
+ Invoke this before mg_write or mg_printf when communicating with a
+ websocket if your code has server-initiated communication as well as
+ communication in direct response to a message. */
+CIVETWEB_API void mg_lock_connection(struct mg_connection* conn);
+CIVETWEB_API void mg_unlock_connection(struct mg_connection* conn);
+
+#if defined(MG_LEGACY_INTERFACE)
+#define mg_lock mg_lock_connection
+#define mg_unlock mg_unlock_connection
+#endif
+
+/* Lock server context. This lock may be used to protect ressources
+ that are shared between different connection/worker threads. */
+CIVETWEB_API void mg_lock_context(struct mg_context* ctx);
+CIVETWEB_API void mg_unlock_context(struct mg_context* ctx);
+
+
+/* Opcodes, from http://tools.ietf.org/html/rfc6455 */
+enum {
+ WEBSOCKET_OPCODE_CONTINUATION = 0x0,
+ WEBSOCKET_OPCODE_TEXT = 0x1,
+ WEBSOCKET_OPCODE_BINARY = 0x2,
+ WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
+ WEBSOCKET_OPCODE_PING = 0x9,
+ WEBSOCKET_OPCODE_PONG = 0xa
+};
+
+
+/* Macros for enabling compiler-specific checks forprintf-like arguments. */
+#undef PRINTF_FORMAT_STRING
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+#include <sal.h>
+#if defined(_MSC_VER) && _MSC_VER > 1400
+#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
+#else
+#define PRINTF_FORMAT_STRING(s) __format_string s
+#endif
+#else
+#define PRINTF_FORMAT_STRING(s) s
+#endif
+
+#ifdef __GNUC__
+#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
+#else
+#define PRINTF_ARGS(x, y)
+#endif
+
+/* Send data to the client usingprintf() semantics.
+ Works exactly like mg_write(), but allows to do message formatting. */
+CIVETWEB_API int mg_printf(struct mg_connection *,
+ PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
+
+
+/* Send contents of the entire file together with HTTP headers. */
+CIVETWEB_API void mg_send_file(struct mg_connection *conn, const char *path);
+
+
+/* Read data from the remote end, return number of bytes read.
+ Return:
+ 0 connection has been closed by peer. No more data could be read.
+ < 0 read error. No more data could be read from the connection.
+ > 0 number of bytes read into the buffer. */
+CIVETWEB_API int mg_read(struct mg_connection *, void *buf, size_t len);
+
+
+/* Get the value of particular HTTP header.
+
+ This is a helper function. It traverses request_info->http_headers array,
+ and if the header is present in the array, returns its value. If it is
+ not present, NULL is returned. */
+CIVETWEB_API const char *mg_get_header(const struct mg_connection *, const char *name);
+
+
+/* Get a value of particular form variable.
+
+ Parameters:
+ data: pointer to form-uri-encoded buffer. This could be either POST data,
+ or request_info.query_string.
+ data_len: length of the encoded data.
+ var_name: variable name to decode from the buffer
+ dst: destination buffer for the decoded variable
+ dst_len: length of the destination buffer
+
+ Return:
+ On success, length of the decoded variable.
+ On error:
+ -1 (variable not found).
+ -2 (destination buffer is NULL, zero length or too small to hold the
+ decoded variable).
+
+ Destination buffer is guaranteed to be '\0' - terminated if it is not
+ NULL or zero length. */
+CIVETWEB_API int mg_get_var(const char *data, size_t data_len,
+ const char *var_name, char *dst, size_t dst_len);
+
+
+/* Get a value of particular form variable.
+
+ Parameters:
+ data: pointer to form-uri-encoded buffer. This could be either POST data,
+ or request_info.query_string.
+ data_len: length of the encoded data.
+ var_name: variable name to decode from the buffer
+ dst: destination buffer for the decoded variable
+ dst_len: length of the destination buffer
+ occurrence: which occurrence of the variable, 0 is the first, 1 the
+ second...
+ this makes it possible to parse a query like
+ b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
+
+ Return:
+ On success, length of the decoded variable.
+ On error:
+ -1 (variable not found).
+ -2 (destination buffer is NULL, zero length or too small to hold the
+ decoded variable).
+
+ Destination buffer is guaranteed to be '\0' - terminated if it is not
+ NULL or zero length. */
+CIVETWEB_API int mg_get_var2(const char *data, size_t data_len,
+ const char *var_name, char *dst, size_t dst_len, size_t occurrence);
+
+
+/* Fetch value of certain cookie variable into the destination buffer.
+
+ Destination buffer is guaranteed to be '\0' - terminated. In case of
+ failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
+ parameter. This function returns only first occurrence.
+
+ Return:
+ On success, value length.
+ On error:
+ -1 (either "Cookie:" header is not present at all or the requested
+ parameter is not found).
+ -2 (destination buffer is NULL, zero length or too small to hold the
+ value). */
+CIVETWEB_API int mg_get_cookie(const char *cookie, const char *var_name,
+ char *buf, size_t buf_len);
+
+
+/* Download data from the remote web server.
+ host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
+ port: port number, e.g. 80.
+ use_ssl: wether to use SSL connection.
+ error_buffer, error_buffer_size: error message placeholder.
+ request_fmt,...: HTTP request.
+ Return:
+ On success, valid pointer to the new connection, suitable for mg_read().
+ On error, NULL. error_buffer contains error message.
+ Example:
+ char ebuf[100];
+ struct mg_connection *conn;
+ conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf),
+ "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
+ */
+CIVETWEB_API struct mg_connection *mg_download(const char *host, int port, int use_ssl,
+ char *error_buffer, size_t error_buffer_size,
+ PRINTF_FORMAT_STRING(const char *request_fmt),
+ ...) PRINTF_ARGS(6, 7);
+
+
+/* Close the connection opened by mg_download(). */
+CIVETWEB_API void mg_close_connection(struct mg_connection *conn);
+
+
+/* File upload functionality. Each uploaded file gets saved into a temporary
+ file and MG_UPLOAD event is sent.
+ Return number of uploaded files. */
+CIVETWEB_API int mg_upload(struct mg_connection *conn, const char *destination_dir);
+
+
+/* Convenience function -- create detached thread.
+ Return: 0 on success, non-0 on error. */
+typedef void * (*mg_thread_func_t)(void *);
+CIVETWEB_API int mg_start_thread(mg_thread_func_t f, void *p);
+
+
+/* Return builtin mime type for the given file name.
+ For unrecognized extensions, "text/plain" is returned. */
+CIVETWEB_API const char *mg_get_builtin_mime_type(const char *file_name);
+
+
+/* Return Civetweb version. */
+CIVETWEB_API const char *mg_version(void);
+
+
+/* URL-decode input buffer into destination buffer.
+ 0-terminate the destination buffer.
+ form-url-encoded data differs from URI encoding in a way that it
+ uses '+' as character for space, see RFC 1866 section 8.2.1
+ http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
+ Return: length of the decoded data, or -1 if dst buffer is too small. */
+CIVETWEB_API int mg_url_decode(const char *src, int src_len, char *dst,
+ int dst_len, int is_form_url_encoded);
+
+
+/* URL-encode input buffer into destination buffer.
+ returns the length of the resulting buffer or -1
+ is the buffer is too small. */
+CIVETWEB_API int mg_url_encode(const char *src, char *dst, size_t dst_len);
+
+
+/* MD5 hash given strings.
+ Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
+ ASCIIz strings. When function returns, buf will contain human-readable
+ MD5 hash. Example:
+ char buf[33];
+ mg_md5(buf, "aa", "bb", NULL); */
+CIVETWEB_API char *mg_md5(char buf[33], ...);
+
+
+/* Print error message to the opened error log stream.
+ This utilizes the provided logging configuration.
+ conn: connection
+ fmt: format string without the line return
+ ...: variable argument list
+ Example:
+ mg_cry(conn,"i like %s", "logging"); */
+CIVETWEB_API void mg_cry(struct mg_connection *conn,
+ PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
+
+
+/* utility method to compare two buffers, case incensitive. */
+CIVETWEB_API int mg_strncasecmp(const char *s1, const char *s2, size_t len);
+
+/* Connect to a websocket as a client
+ Parameters:
+ host: host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost"
+ port: server port
+ use_ssl: make a secure connection to server
+ error_buffer, error_buffer_size: buffer for an error message
+ path: server path you are trying to connect to, i.e. if connection to localhost/app, path should be "/app"
+ origin: value of the Origin HTTP header
+ data_func: callback that should be used when data is received from the server
+ user_data: user supplied argument
+
+ Return:
+ On success, valid mg_connection object.
+ On error, NULL. Se error_buffer for details.
+*/
+
+typedef int (*websocket_data_func)(struct mg_connection *, int bits,
+ char *data, size_t data_len);
+
+typedef void (*websocket_close_func)(struct mg_connection *);
+
+CIVETWEB_API struct mg_connection *mg_connect_websocket_client(const char *host, int port, int use_ssl,
+ char *error_buffer, size_t error_buffer_size,
+ const char *path, const char *origin,
+ websocket_data_func data_func, websocket_close_func close_func,
+ void * user_data);
+
+/* Connect to a TCP server as a client (can be used to connect to a HTTP server)
+ Parameters:
+ host: host to connect to, i.e. "www.wikipedia.org" or "192.168.1.1" or "localhost"
+ port: server port
+ use_ssl: make a secure connection to server
+ error_buffer, error_buffer_size: buffer for an error message
+
+ Return:
+ On success, valid mg_connection object.
+ On error, NULL. Se error_buffer for details.
+*/
+CIVETWEB_API struct mg_connection *mg_connect_client(const char *host, int port, int use_ssl,
+ char *error_buffer, size_t error_buffer_size);
+
+
+enum {
+ TIMEOUT_INFINITE = -1
+};
+
+/* Wait for a response from the server
+ Parameters:
+ conn: connection
+ ebuf, ebuf_len: error message placeholder.
+ timeout: time to wait for a response in milliseconds (if < 0 then wait forever)
+
+ Return:
+ On success, >= 0
+ On error/timeout, < 0
+*/
+CIVETWEB_API int mg_get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int timeout);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CIVETWEB_HEADER_INCLUDED */
[8/8] celix git commit: CELIX-417: Renames remote services target.
Mostly adding the rsa prefix
Posted by pn...@apache.org.
CELIX-417: Renames remote services target. Mostly adding the rsa prefix
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/486d4f0d
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/486d4f0d
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/486d4f0d
Branch: refs/heads/feature/CELIX-417-cmake-refactor
Commit: 486d4f0d5c86f0770f047e3ecc4caf77af9886a7
Parents: 27a2aa7
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Nov 24 11:58:59 2017 +0100
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Nov 24 11:58:59 2017 +0100
----------------------------------------------------------------------
remote_services/CMakeLists.txt | 1 -
remote_services/civetweb/CMakeLists.txt | 5 +-
remote_services/discovery_common/CMakeLists.txt | 10 +--
.../src/endpoint_descriptor_reader.c | 94 --------------------
.../src/endpoint_descriptor_writer.c | 37 --------
.../discovery_configured/CMakeLists.txt | 35 +++-----
remote_services/discovery_etcd/CMakeLists.txt | 23 ++---
remote_services/discovery_shm/CMakeLists.txt | 19 ++--
remote_services/examples/CMakeLists.txt | 4 +-
.../examples/calculator_service/CMakeLists.txt | 2 +-
.../remote_service_admin_api/CMakeLists.txt | 6 +-
.../remote_service_admin_common/CMakeLists.txt | 9 +-
.../remote_service_admin_dfi/CMakeLists.txt | 14 +--
.../test/CMakeLists.txt | 11 ++-
remote_services/topology_manager/CMakeLists.txt | 13 +--
.../topology_manager/tms_tst/CMakeLists.txt | 10 +--
.../tms_tst/bundle/CMakeLists.txt | 2 +-
.../tms_tst/disc_mock/CMakeLists.txt | 2 +-
18 files changed, 79 insertions(+), 218 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/CMakeLists.txt b/remote_services/CMakeLists.txt
index 4e1f5b3..bb45908 100644
--- a/remote_services/CMakeLists.txt
+++ b/remote_services/CMakeLists.txt
@@ -23,7 +23,6 @@ if (REMOTE_SERVICE_ADMIN)
add_subdirectory(topology_manager)
add_subdirectory(civetweb)
-
add_subdirectory(discovery_common)
add_subdirectory(discovery_configured)
add_subdirectory(discovery_etcd)
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/civetweb/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/civetweb/CMakeLists.txt b/remote_services/civetweb/CMakeLists.txt
index e9e272e..a6f7d10 100644
--- a/remote_services/civetweb/CMakeLists.txt
+++ b/remote_services/civetweb/CMakeLists.txt
@@ -20,4 +20,7 @@ add_library(civetweb OBJECT
src/civetweb.c
src/md5.inl
)
-target_include_directories(civetweb PUBLIC include)
\ No newline at end of file
+target_include_directories(civetweb PUBLIC include)
+
+#Setup target aliases to match external usage
+add_library(Celix::civetweb ALIAS civetweb)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/discovery_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/CMakeLists.txt b/remote_services/discovery_common/CMakeLists.txt
index 5b28b13..c3242a6 100644
--- a/remote_services/discovery_common/CMakeLists.txt
+++ b/remote_services/discovery_common/CMakeLists.txt
@@ -18,7 +18,7 @@
find_package(LibXml2 REQUIRED)
-add_library(discovery_common OBJECT
+add_library(rsa_discovery_common OBJECT
src/discovery.c
src/discovery_activator.c
src/endpoint_descriptor_reader.c
@@ -26,14 +26,14 @@ add_library(discovery_common OBJECT
src/endpoint_discovery_poller.c
src/endpoint_discovery_server.c
)
-target_include_directories(discovery_common PUBLIC
+target_include_directories(rsa_discovery_common PUBLIC
include src
$<TARGET_PROPERTY:Celix::framework,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:Celix::utils,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:Celix::log_helper,INTERFACE_INCLUDE_DIRECTORIES>
- $<TARGET_PROPERTY:Celix::remote_service_admin_api,INTERFACE_INCLUDE_DIRECTORIES>
- $<TARGET_PROPERTY:Celix::remote_service_admin_api,INTERFACE_INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::rsa_api,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>
${LIBXML2_INCLUDE_DIR})
-add_library(Celix::discovery_common ALIAS discovery_common)
\ No newline at end of file
+#Setup target aliases to match external usage
+add_library(Celix::rsa_discovery_common ALIAS rsa_discovery_common)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/discovery_common/src/endpoint_descriptor_reader.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_descriptor_reader.c b/remote_services/discovery_common/src/endpoint_descriptor_reader.c
index ea176bf..887bc29 100644
--- a/remote_services/discovery_common/src/endpoint_descriptor_reader.c
+++ b/remote_services/discovery_common/src/endpoint_descriptor_reader.c
@@ -291,97 +291,3 @@ static valueType valueTypeFromString(char *name) {
}
}
-#ifdef RSA_ENDPOINT_TEST_READER
-int main() {
- array_list_pt list = NULL;
- endpoint_descriptor_reader_pt reader = NULL;
-
- char *doc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-"<endpoint-descriptions xmlns=\"http://www.osgi.org/xmlns/rsa/v1.0.0\">"
- "<endpoint-description>"
- "<property name=\"endpoint.service.id\" value-type=\"long\" value=\"6\"/>"
- "<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>"
- "<property name=\"service.intents\">"
- "<list>"
- "<value>SOAP</value>"
- "<value>HTTP</value>"
- "</list>"
- "</property>"
- "<property name=\"endpoint.id\" value=\"11111111-1111-1111-1111-111111111111\" />"
- "<property name=\"objectClass\"><array><value>com.acme.Foo</value></array></property>"
- "<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />"
- "<property name=\"service.imported.configs\" value=\"com.acme\" />"
- "<property name=\"service.imported\" value=\"true\"/>"
- "<property name=\"com.acme.ws.xml\">"
- "<xml>"
- "<config xmlns=\"http://acme.com/defs\">"
- "<port>1029</port>"
- "<host>www.acme.com</host>"
- "</config>"
- "</xml>"
- "</property>"
- "</endpoint-description>"
- "<endpoint-description>"
- "<property name=\"endpoint.service.id\" value-type=\"long\" value=\"5\"/>"
- "<property name=\"endpoint.framework.uuid\" value=\"2983D849-93B1-4C2C-AC6D-5BCDA93ACB96\"/>"
- "<property name=\"service.intents\">"
- "<list>"
- "<value>SOAP</value>"
- "<value>HTTP</value>"
- "</list>"
- "</property>"
- "<property name=\"endpoint.id\" value=\"22222222-2222-2222-2222-222222222222\" />"
- "<property name=\"objectClass\"><array><value>com.acme.Bar</value></array></property>"
- "<property name=\"endpoint.package.version.com.acme\" value=\"4.2\" />"
- "<property name=\"service.imported.configs\" value=\"com.acme\" />"
- "<property name=\"com.acme.ws.xml\">"
- "<xml>"
- "<config xmlns=\"http://acme.com/defs\">"
- "<port>1029</port>"
- "<host>www.acme.com</host>"
- "</config>"
- "</xml>"
- "</property>"
- "</endpoint-description>"
- "</endpoint-descriptions>";
-
- endpointDescriptorReader_create(&reader);
-
- endpointDescriptorReader_parseDocument(reader, doc, &list);
-
- int i;
- for (i = 0; i < arrayList_size(list); i++) {
- printf("\nEndpoint description #%d:\n", (i+1));
- endpoint_description_pt edp = arrayList_get(list, i);
- printf("Id: %s\n", edp->id);
- printf("Service Id: %lu\n", edp->serviceId);
- printf("Framework UUID: %s\n", edp->frameworkUUID);
- printf("Service: %s\n", edp->service);
-
- properties_pt props = edp->properties;
- if (props) {
- printf("Service properties:\n");
- hash_map_iterator_pt iter = hashMapIterator_create(props);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-
- printf("- %s => '%s'\n", hashMapEntry_getKey(entry), hashMapEntry_getValue(entry));
- }
- hashMapIterator_destroy(iter);
- } else {
- printf("No service properties...\n");
- }
-
-
- endpointDescription_destroy(edp);
- }
-
- if (list != NULL) {
- arrayList_destroy(list);
- }
-
- endpointDescriptorReader_destroy(reader);
-
- return 0;
-}
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/discovery_common/src/endpoint_descriptor_writer.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_descriptor_writer.c b/remote_services/discovery_common/src/endpoint_descriptor_writer.c
index 71b07b4..4a5bcd7 100644
--- a/remote_services/discovery_common/src/endpoint_descriptor_writer.c
+++ b/remote_services/discovery_common/src/endpoint_descriptor_writer.c
@@ -194,40 +194,3 @@ static char* valueTypeToString(valueType type) {
return "string";
}
}
-
-#ifdef RSA_ENDPOINT_TEST_WRITER
-int main() {
- endpoint_descriptor_writer_pt writer = NULL;
- endpointDescriptorWriter_create(&writer);
- array_list_pt list = NULL;
- arrayList_create(&list);
-
- properties_pt props = properties_create();
- properties_set(props, "objectClass", "com.acme.Foo");
- properties_set(props, "endpoint.service.id", "3");
- properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz");
- properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96");
- endpoint_description_pt epd = NULL;
- endpointDescription_create(props, &epd);
- arrayList_add(list, epd);
-
- properties_pt props2 = properties_create();
- properties_set(props2, "objectClass", "com.acme.Bar");
- properties_set(props, "endpoint.service.id", "4");
- properties_set(props, "endpoint.id", "abcdefghijklmnopqrstuvwxyz");
- properties_set(props, "endpoint.framework.uuid", "2983D849-93B1-4C2C-AC6D-5BCDA93ACB96");
- endpoint_description_pt epd2 = NULL;
- endpointDescription_create(props2, &epd2);
- arrayList_add(list, epd2);
-
- char *buffer = NULL;
- endpointDescriptorWriter_writeDocument(writer, list, &buffer);
-
- arrayList_destroy(list);
- endpointDescription_destroy(epd);
- endpointDescription_destroy(epd2);
- endpointDescriptorWriter_destroy(writer);
-
- printf("%s\n", buffer);
-}
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/discovery_configured/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/CMakeLists.txt b/remote_services/discovery_configured/CMakeLists.txt
index f7d104b..bea485e 100644
--- a/remote_services/discovery_configured/CMakeLists.txt
+++ b/remote_services/discovery_configured/CMakeLists.txt
@@ -19,39 +19,24 @@ if (RSA_DISCOVERY_CONFIGURED)
find_package(CURL REQUIRED)
find_package(LibXml2 REQUIRED)
- add_bundle(discovery_configured
+ add_bundle(rsa_discovery_configured
VERSION 0.9.0
SYMBOLIC_NAME "apache_celix_rsa_discovery_configured"
NAME "Apache Celix RSA Configured Discovery"
SOURCES
src/discovery_impl.c
- $<TARGET_OBJECTS:discovery_common>
- $<TARGET_OBJECTS:civetweb>
+ $<TARGET_OBJECTS:Celix::rsa_discovery_common>
+ $<TARGET_OBJECTS:Celix::civetweb>
)
- target_include_directories(discovery_configured PRIVATE
+ target_include_directories(rsa_discovery_configured PRIVATE
src
- $<TARGET_PROPERTY:discovery_common,INCLUDE_DIRECTORIES>
- $<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::rsa_discovery_common,INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::civetweb,INCLUDE_DIRECTORIES>
)
- target_link_libraries(discovery_configured PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} Celix::log_helper)
+ target_link_libraries(rsa_discovery_configured PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} Celix::log_helper)
- install_bundle(discovery_configured)
+ install_bundle(rsa_discovery_configured)
-
-
- if (RSA_ENDPOINT_TEST_READER)
- add_executable(descparser
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_reader.c
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c)
-
- target_link_libraries(descparser ${LIBXML2_LIBRARIES} celix_framework celix_utils)
- endif (RSA_ENDPOINT_TEST_READER)
-
- if (RSA_ENDPOINT_TEST_WRITER)
- add_executable(descwriter
- ${PROJECT_SOURCE_DIR}/remote_services/discovery/private/src/endpoint_descriptor_writer.c
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c)
-
- target_link_libraries(descwriter ${LIBXML2_LIBRARIES} celix_framework celix_utils)
- endif(RSA_ENDPOINT_TEST_WRITER)
+ #Setup target aliases to match external usage
+ add_library(Celix::rsa_discovery_configured ALIAS rsa_discovery_configured)
endif (RSA_DISCOVERY_CONFIGURED)
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/discovery_etcd/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_etcd/CMakeLists.txt b/remote_services/discovery_etcd/CMakeLists.txt
index 9c8edc8..19726fc 100644
--- a/remote_services/discovery_etcd/CMakeLists.txt
+++ b/remote_services/discovery_etcd/CMakeLists.txt
@@ -21,26 +21,29 @@ if (RSA_DISCOVERY_ETCD)
find_package(LibXml2 REQUIRED)
find_package(Jansson REQUIRED)
- add_bundle(discovery_etcd
+ add_bundle(rsa_discovery_etcd
VERSION 0.9.0
SYMBOLIC_NAME "apache_celix_rsa_discovery_etcd"
NAME "Apache Celix RSA Discovery ETCD"
SOURCES
src/discovery_impl.c
src/etcd_watcher.c
- $<TARGET_OBJECTS:discovery_common>
- $<TARGET_OBJECTS:civetweb>
+ $<TARGET_OBJECTS:Celix::rsa_discovery_common>
+ $<TARGET_OBJECTS:Celix::civetweb>
)
- target_link_libraries(discovery_etcd PRIVATE Celix::log_helper Celix::etcdlib_static)
- target_include_directories(discovery_etcd PRIVATE src)
- target_include_directories(discovery_etcd PRIVATE
- $<TARGET_PROPERTY:discovery_common,INCLUDE_DIRECTORIES>
- $<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>
+ target_link_libraries(rsa_discovery_etcd PRIVATE Celix::log_helper Celix::etcdlib_static)
+ target_include_directories(rsa_discovery_etcd PRIVATE src)
+ target_include_directories(rsa_discovery_etcd PRIVATE
+ $<TARGET_PROPERTY:Celix::rsa_discovery_common,INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::civetweb,INCLUDE_DIRECTORIES>
${CURL_INCLUDE_DIR}
${JANSSON_INCLUDE_DIR}
${LIBXML2_INCLUDE_DIR}
)
- target_link_libraries(discovery_etcd PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} ${JANSSON_LIBRARIES})
+ target_link_libraries(rsa_discovery_etcd PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} ${JANSSON_LIBRARIES})
- install_bundle(discovery_etcd)
+ install_bundle(rsa_discovery_etcd)
+
+ #Setup target aliases to match external usage
+ add_library(Celix::rsa_discovery_etcd ALIAS rsa_discovery_etcd)
endif (RSA_DISCOVERY_ETCD)
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/discovery_shm/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/CMakeLists.txt b/remote_services/discovery_shm/CMakeLists.txt
index 61e54f7..fd822e6 100644
--- a/remote_services/discovery_shm/CMakeLists.txt
+++ b/remote_services/discovery_shm/CMakeLists.txt
@@ -20,7 +20,7 @@ if (RSA_DISCOVERY_SHM)
find_package(CURL REQUIRED)
find_package(LibXml2 REQUIRED)
- add_bundle(discovery_shm
+ add_bundle(rsa_discovery_shm
VERSION 0.0.1
SYMBOLIC_NAME "apache_celix_rsa_discovery_shm"
NAME "Apache Celix RSA Discovery SHM"
@@ -28,20 +28,21 @@ find_package(CURL REQUIRED)
src/discovery_shm.c
src/discovery_shmWatcher.c
src/discovery_impl.c
- $<TARGET_OBJECTS:discovery_common>
- $<TARGET_OBJECTS:civetweb>
+ $<TARGET_OBJECTS:Celix::rsa_discovery_common>
+ $<TARGET_OBJECTS:Celix::civetweb>
)
- target_include_directories(discovery_shm PRIVATE
+ target_include_directories(rsa_discovery_shm PRIVATE
src
${LIBXML2_INCLUDE_DIR}
${CURL_INCLUDE_DIR}
- $<TARGET_PROPERTY:discovery_common,INCLUDE_DIRECTORIES>
- $<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::rsa_discovery_common,INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::civetweb,INCLUDE_DIRECTORIES>
)
- target_link_libraries(discovery_shm PRIVATE Celix::framework ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES})
+ target_link_libraries(rsa_discovery_shm PRIVATE Celix::framework ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES})
- install_bundle(discovery_shm)
-
+ install_bundle(rsa_discovery_shm)
+ #Setup target aliases to match external usage
+ add_library(Celix::rsa_discovery_shm ALIAS rsa_discovery_shm)
endif (RSA_DISCOVERY_SHM)
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/CMakeLists.txt b/remote_services/examples/CMakeLists.txt
index 2b1f35f..78bfbac 100644
--- a/remote_services/examples/CMakeLists.txt
+++ b/remote_services/examples/CMakeLists.txt
@@ -48,13 +48,13 @@ if (RSA_EXAMPLES)
add_deploy(remote-services-dfi
NAME "server"
GROUP "remote-services/remote-services-dfi"
- BUNDLES discovery_etcd topology_manager remote_service_admin_dfi calculator Celix::shell Celix::shell_tui Celix::log_service Celix::log_writer_stdout
+ BUNDLES Celix::rsa_discovery_etcd Celix::rsa_topology_manager Celix::rsa_dfi calculator Celix::shell Celix::shell_tui Celix::log_service Celix::log_writer_stdout
)
add_deploy("remote-services-dfi-client"
NAME "client"
GROUP "remote-services/remote-services-dfi"
- BUNDLES topology_manager remote_service_admin_dfi Celix::shell Celix::shell_tui Celix::log_service Celix::log_writer_stdout calculator_shell discovery_etcd
+ BUNDLES Celix::rsa_topology_manager Celix::rsa_dfi Celix::shell Celix::shell_tui Celix::log_service Celix::log_writer_stdout calculator_shell Celix::rsa_discovery_etcd
)
endif ()
endif (RSA_EXAMPLES)
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/examples/calculator_service/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/examples/calculator_service/CMakeLists.txt b/remote_services/examples/calculator_service/CMakeLists.txt
index ff4d2d7..5d97d16 100644
--- a/remote_services/examples/calculator_service/CMakeLists.txt
+++ b/remote_services/examples/calculator_service/CMakeLists.txt
@@ -23,7 +23,7 @@ add_bundle(calculator
VERSION 0.0.1
)
target_include_directories(calculator PRIVATE src)
-target_link_libraries(calculator PRIVATE Celix::remote_service_admin_api calculator_api)
+target_link_libraries(calculator PRIVATE Celix::rsa_api calculator_api)
get_target_property(DESCR calculator_api INTERFACE_CALCULATOR_DESCRIPTOR)
bundle_files(calculator ${DESCR} DESTINATION .)
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/remote_service_admin_api/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_api/CMakeLists.txt b/remote_services/remote_service_admin_api/CMakeLists.txt
index a7d0640..f665576 100644
--- a/remote_services/remote_service_admin_api/CMakeLists.txt
+++ b/remote_services/remote_service_admin_api/CMakeLists.txt
@@ -15,8 +15,8 @@
# specific language governing permissions and limitations
# under the License.
-add_library(remote_service_admin_api INTERFACE)
-target_include_directories(remote_service_admin_api INTERFACE include)
+add_library(rsa_api INTERFACE)
+target_include_directories(rsa_api INTERFACE include)
install (FILES
include/remote_endpoint_impl.h
@@ -42,4 +42,4 @@ install (FILES
)
#Setup target aliases to match external usage
-add_library(Celix::remote_service_admin_api ALIAS remote_service_admin_api)
+add_library(Celix::rsa_api ALIAS rsa_api)
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/remote_service_admin_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/CMakeLists.txt b/remote_services/remote_service_admin_common/CMakeLists.txt
index a421cda..018d868 100644
--- a/remote_services/remote_service_admin_common/CMakeLists.txt
+++ b/remote_services/remote_service_admin_common/CMakeLists.txt
@@ -15,12 +15,13 @@
# specific language governing permissions and limitations
# under the License.
-add_library(remote_service_admin_common STATIC
+add_library(rsa_common STATIC
src/endpoint_description.c
src/export_registration_impl.c
src/import_registration_impl.c
)
-target_include_directories(remote_service_admin_common PRIVATE src)
-target_link_libraries(remote_service_admin_common PUBLIC Celix::framework Celix::remote_service_admin_api Celix::log_helper)
+target_include_directories(rsa_common PRIVATE src)
+target_link_libraries(rsa_common PUBLIC Celix::framework Celix::rsa_api Celix::log_helper)
-add_library(Celix::remote_service_admin_common ALIAS remote_service_admin_common)
\ No newline at end of file
+#Setup target aliases to match external usage
+add_library(Celix::rsa_common ALIAS rsa_common)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/remote_service_admin_dfi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/CMakeLists.txt b/remote_services/remote_service_admin_dfi/CMakeLists.txt
index 206c6dc..ea79c31 100644
--- a/remote_services/remote_service_admin_dfi/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/CMakeLists.txt
@@ -23,7 +23,7 @@ if (RSA_REMOTE_SERVICE_ADMIN_DFI)
find_package(CURL REQUIRED)
find_package(Jansson REQUIRED)
- add_bundle(remote_service_admin_dfi
+ add_bundle(rsa_dfi
VERSION 0.9.0
SYMBOLIC_NAME "apache_celix_remote_service_admin_dfi"
NAME "Apache Celix Remote Service Admin Dynamic Function Interface (DFI)"
@@ -33,21 +33,21 @@ if (RSA_REMOTE_SERVICE_ADMIN_DFI)
src/export_registration_dfi.c
src/import_registration_dfi.c
src/dfi_utils.c
- $<TARGET_OBJECTS:civetweb>
+ $<TARGET_OBJECTS:Celix::civetweb>
)
- target_include_directories(remote_service_admin_dfi PRIVATE src $<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>)
- target_link_libraries(remote_service_admin_dfi PRIVATE
+ target_include_directories(rsa_dfi PRIVATE src $<TARGET_PROPERTY:Celix::civetweb,INCLUDE_DIRECTORIES>)
+ target_link_libraries(rsa_dfi PRIVATE
Celix::dfi_static
Celix::log_helper
- Celix::remote_service_admin_common
+ Celix::rsa_common
${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
- install_bundle(remote_service_admin_dfi)
+ install_bundle(rsa_dfi)
if (ENABLE_TESTING)
add_subdirectory(test)
endif()
#Setup target aliases to match external usage
- add_library(Celix::remote_service_admin_dfi ALIAS remote_service_admin_dfi)
+ add_library(Celix::rsa_dfi ALIAS rsa_dfi)
endif()
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/test/CMakeLists.txt b/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
index a78a6d0..153b3d1 100644
--- a/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
@@ -36,15 +36,14 @@ add_executable(test_rsa_dfi
target_include_directories(test_rsa_dfi PRIVATE src)
target_link_libraries(test_rsa_dfi PRIVATE ${CURL_LIBRARIES} ${CPPUTEST_LIBRARY}
Celix::framework
- Celix::remote_service_admin_api
- Celix::remote_service_admin_common
+ Celix::rsa_common
calculator_api)
-get_property(rsa_bundle_file TARGET remote_service_admin_dfi PROPERTY BUNDLE_FILE)
+get_property(rsa_bundle_file TARGET rsa_dfi PROPERTY BUNDLE_FILE)
get_property(calc_bundle_file TARGET calculator PROPERTY BUNDLE_FILE)
get_property(calculator_shell_bundle_file TARGET calculator_shell PROPERTY BUNDLE_FILE)
-get_property(discovery_configured_bundle_file TARGET discovery_configured PROPERTY BUNDLE_FILE)
-get_property(topology_manager_bundle_file TARGET topology_manager PROPERTY BUNDLE_FILE)
+get_property(discovery_configured_bundle_file TARGET rsa_discovery_configured PROPERTY BUNDLE_FILE)
+get_property(topology_manager_bundle_file TARGET Celix::rsa_topology_manager PROPERTY BUNDLE_FILE)
get_property(tst_bundle_file TARGET rsa_dfi_tst_bundle PROPERTY BUNDLE_FILE)
configure_file(config.properties.in config.properties)
@@ -52,7 +51,7 @@ configure_file(client.properties.in client.properties)
configure_file(server.properties.in server.properties)
add_dependencies(test_rsa_dfi
- remote_service_admin_dfi_bundle #note depend on the target creating the bundle zip not the lib target
+ rsa_dfi_bundle #note depend on the target creating the bundle zip not the lib target
calculator_bundle
)
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/topology_manager/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/CMakeLists.txt b/remote_services/topology_manager/CMakeLists.txt
index defee5c..568054e 100644
--- a/remote_services/topology_manager/CMakeLists.txt
+++ b/remote_services/topology_manager/CMakeLists.txt
@@ -17,7 +17,7 @@
celix_subproject(RSA_TOPOLOGY_MANAGER "Option to enable building the Remote Service Admin Service SHM bundle" ON DEPS REMOTE_SERVICE_ADMIN_DFI)
if (RSA_TOPOLOGY_MANAGER)
- add_bundle(topology_manager
+ add_bundle(rsa_topology_manager
SOURCES
src/topology_manager
src/scope
@@ -26,11 +26,11 @@ if (RSA_TOPOLOGY_MANAGER)
SYMBOLIC_NAME "apache_celix_rs_topology_manager"
NAME "Apache Celix RS Topology Manager"
)
- target_include_directories(topology_manager PRIVATE src)
- target_include_directories(topology_manager PUBLIC include)
- target_link_libraries(topology_manager PRIVATE Celix::log_helper remote_service_admin_api)
+ target_include_directories(rsa_topology_manager PRIVATE src)
+ target_include_directories(rsa_topology_manager PUBLIC include)
+ target_link_libraries(rsa_topology_manager PRIVATE Celix::log_helper Celix::rsa_api)
- install_bundle(topology_manager)
+ install_bundle(rsa_topology_manager)
if (ENABLE_TESTING)
find_package(CppUTest REQUIRED)
@@ -41,4 +41,7 @@ if (RSA_TOPOLOGY_MANAGER)
include_directories(${CPPUTEST_EXT_INCLUDE_DIR})
add_subdirectory(tms_tst)
endif (ENABLE_TESTING)
+
+ #Setup target aliases to match external usage
+ add_library(Celix::rsa_topology_manager ALIAS rsa_topology_manager)
endif (RSA_TOPOLOGY_MANAGER)
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/topology_manager/tms_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/CMakeLists.txt b/remote_services/topology_manager/tms_tst/CMakeLists.txt
index 5e27139..6dedf32 100644
--- a/remote_services/topology_manager/tms_tst/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/CMakeLists.txt
@@ -42,18 +42,16 @@ target_link_libraries(test_tm_scoped PRIVATE
Celix::framework
${CPPUTEST_LIBRARY}
${JANSSON_LIBRARY}
- Celix::log_helper
calculator_api
- Celix::remote_service_admin_api
- Celix::remote_service_admin_common
+ Celix::rsa_common
)
-add_dependencies(test_tm_scoped remote_service_admin_dfi_bundle topology_manager_bundle)
+add_dependencies(test_tm_scoped rsa_dfi_bundle rsa_topology_manager_bundle)
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config.properties"
CONTENT "
-cosgi.auto.start.1=$<TARGET_PROPERTY:remote_service_admin_dfi,BUNDLE_FILE> $<TARGET_PROPERTY:calculator,BUNDLE_FILE> $<TARGET_PROPERTY:topology_manager,BUNDLE_FILE> $<TARGET_PROPERTY:topology_manager_disc_mock_bundle,BUNDLE_FILE>
+cosgi.auto.start.1=$<TARGET_PROPERTY:Celix::rsa_dfi,BUNDLE_FILE> $<TARGET_PROPERTY:calculator,BUNDLE_FILE> $<TARGET_PROPERTY:Celix::rsa_topology_manager,BUNDLE_FILE> $<TARGET_PROPERTY:topology_manager_disc_mock_bundle,BUNDLE_FILE>
LOGHELPER_ENABLE_STDOUT_FALLBACK=true
org.osgi.framework.storage.clean=onFirstInit
")
@@ -61,7 +59,7 @@ org.osgi.framework.storage.clean=onFirstInit
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config_import.properties"
CONTENT "
-cosgi.auto.start.1=$<TARGET_PROPERTY:remote_service_admin_dfi,BUNDLE_FILE> $<TARGET_PROPERTY:calculator,BUNDLE_FILE> $<TARGET_PROPERTY:topology_manager,BUNDLE_FILE> $<TARGET_PROPERTY:topology_manager_test_bundle,BUNDLE_FILE>
+cosgi.auto.start.1=$<TARGET_PROPERTY:Celix::rsa_dfi,BUNDLE_FILE> $<TARGET_PROPERTY:calculator,BUNDLE_FILE> $<TARGET_PROPERTY:Celix::rsa_topology_manager,BUNDLE_FILE> $<TARGET_PROPERTY:topology_manager_test_bundle,BUNDLE_FILE>
LOGHELPER_ENABLE_STDOUT_FALLBACK=true
org.osgi.framework.storage.clean=onFirstInit
")
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
index 551995b..eaf0a26 100644
--- a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt
@@ -32,4 +32,4 @@ bundle_files(topology_manager_test_bundle
DESTINATION .
)
-target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::remote_service_admin_api calculator_api)
+target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::rsa_api calculator_api)
http://git-wip-us.apache.org/repos/asf/celix/blob/486d4f0d/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt b/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
index 653b69c..3e93174 100644
--- a/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
+++ b/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt
@@ -23,6 +23,6 @@ add_bundle(topology_manager_disc_mock_bundle
)
target_include_directories(topology_manager_disc_mock_bundle PRIVATE
${CPPUTEST_INCLUDE_DIR}
- $<TARGET_PROPERTY:discovery_common,INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::rsa_discovery_common,INCLUDE_DIRECTORIES>
)
target_link_libraries(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::framework)
[3/8] celix git commit: CELIX-417: Refactors CMake usage for the RSA
bundles
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/src/discovery.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/discovery.c b/remote_services/discovery_common/src/discovery.c
index d124c15..d016c09 100644
--- a/remote_services/discovery_common/src/discovery.c
+++ b/remote_services/discovery_common/src/discovery.c
@@ -33,7 +33,6 @@
#include "log_helper.h"
#include "discovery.h"
#include "endpoint_discovery_server.h"
-#include "discovery_impl.h" //TODO rename impl
celix_status_t discovery_endpointAdded(void *handle, endpoint_description_pt endpoint, char *matchedFilter) {
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/src/endpoint_discovery_poller.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_discovery_poller.c b/remote_services/discovery_common/src/endpoint_discovery_poller.c
index 73fb7ba..e3f9cd4 100644
--- a/remote_services/discovery_common/src/endpoint_discovery_poller.c
+++ b/remote_services/discovery_common/src/endpoint_discovery_poller.c
@@ -35,9 +35,8 @@
#include "log_helper.h"
#include "utils.h"
-#include "discovery_impl.h"
-
#include "endpoint_descriptor_reader.h"
+#include "discovery.h"
#define DISCOVERY_POLL_INTERVAL "DISCOVERY_CFG_POLL_INTERVAL"
@@ -52,7 +51,7 @@ static celix_status_t endpointDiscoveryPoller_endpointDescriptionEquals(const vo
/**
* Allocates memory and initializes a new endpoint_discovery_poller instance.
*/
-celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller) {
+celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, const char* defaultPollEndpoints, endpoint_discovery_poller_pt *poller) {
celix_status_t status;
*poller = malloc(sizeof(struct endpoint_discovery_poller));
@@ -76,7 +75,7 @@ celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_con
const char* endpointsProp = NULL;
status = bundleContext_getProperty(context, DISCOVERY_POLL_ENDPOINTS, &endpointsProp);
if (!endpointsProp) {
- endpointsProp = DEFAULT_POLL_ENDPOINTS;
+ endpointsProp = defaultPollEndpoints;
}
// we're going to mutate the string with strtok, so create a copy...
char* endpoints = strdup(endpointsProp);
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/src/endpoint_discovery_server.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/endpoint_discovery_server.c b/remote_services/discovery_common/src/endpoint_discovery_server.c
index f5f82af..7620bbf 100644
--- a/remote_services/discovery_common/src/endpoint_discovery_server.c
+++ b/remote_services/discovery_common/src/endpoint_discovery_server.c
@@ -35,8 +35,6 @@
#include "utils.h"
#include "log_helper.h"
#include "discovery.h"
-#include "discovery_impl.h"
-
#include "endpoint_descriptor_writer.h"
// defines how often the webserver is restarted (with an increased port number)
@@ -72,7 +70,13 @@ static char* format_path(const char* path);
static celix_status_t endpointDiscoveryServer_getIpAdress(char* interface, char** ip);
#endif
-celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server) {
+celix_status_t endpointDiscoveryServer_create(
+ discovery_pt discovery,
+ bundle_context_pt context,
+ const char* defaultServerPath,
+ const char* defaultServerPort,
+ const char* defaultServerIp,
+ endpoint_discovery_server_pt *server) {
celix_status_t status;
const char *port = NULL;
@@ -122,8 +126,8 @@ celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_con
(*server)->ip = strdup(ip);
}
else {
- logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "No IP address for service annunciation set. Using %s", DEFAULT_SERVER_IP);
- (*server)->ip = strdup((char*) DEFAULT_SERVER_IP);
+ logHelper_log(*(*server)->loghelper, OSGI_LOGSERVICE_WARNING, "No IP address for service annunciation set. Using %s", defaultServerIp);
+ (*server)->ip = strdup((char*) defaultServerIp);
}
if (detectedIp != NULL) {
@@ -132,12 +136,12 @@ celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_con
bundleContext_getProperty(context, DISCOVERY_SERVER_PORT, &port);
if (port == NULL) {
- port = DEFAULT_SERVER_PORT;
+ port = defaultServerPort;
}
bundleContext_getProperty(context, DISCOVERY_SERVER_PATH, &path);
if (path == NULL) {
- path = DEFAULT_SERVER_PATH;
+ path = defaultServerPath;
}
bundleContext_getProperty(context, DISCOVERY_SERVER_MAX_EP, &retries);
@@ -177,7 +181,7 @@ celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_con
long currentPort = strtol(port, &endptr, 10);
if (*endptr || errno != 0) {
- currentPort = strtol(DEFAULT_SERVER_PORT, NULL, 10);
+ currentPort = strtol(defaultServerPort, NULL, 10);
}
port_counter++;
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/src/md5.inl
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/md5.inl b/remote_services/discovery_common/src/md5.inl
deleted file mode 100644
index 4da933d..0000000
--- a/remote_services/discovery_common/src/md5.inl
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * This an amalgamation of md5.c and md5.h into a single file
- * with all static declaration to reduce linker conflicts
- * in Civetweb.
- *
- * The MD5_STATIC declaration was added to facilitate static
- * inclusion.
- * No Face Press, LLC
- */
-
-/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
-/*
- Independent implementation of MD5 (RFC 1321).
-
- This code implements the MD5 Algorithm defined in RFC 1321, whose
- text is available at
- http://www.ietf.org/rfc/rfc1321.txt
- The code is derived from the text of the RFC, including the test suite
- (section A.5) but excluding the rest of Appendix A. It does not include
- any code or documentation that is identified in the RFC as being
- copyrighted.
-
- The original and principal author of md5.h is L. Peter Deutsch
- <gh...@aladdin.com>. Other authors are noted in the change history
- that follows (in reverse chronological order):
-
- 2002-04-13 lpd Removed support for non-ANSI compilers; removed
- references to Ghostscript; clarified derivation from RFC 1321;
- now handles byte order either statically or dynamically.
- 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
- 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
- added conditionalization for C++ compilation from Martin
- Purschke <pu...@bnl.gov>.
- 1999-05-03 lpd Original version.
- */
-
-#ifndef md5_INCLUDED
-# define md5_INCLUDED
-
-/*
- * This package supports both compile-time and run-time determination of CPU
- * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
- * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
- * defined as non-zero, the code will be compiled to run only on big-endian
- * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
- * run on either big- or little-endian CPUs, but will run slightly less
- * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
- */
-
-typedef unsigned char md5_byte_t; /* 8-bit byte */
-typedef unsigned int md5_word_t; /* 32-bit word */
-
-/* Define the state of the MD5 Algorithm. */
-typedef struct md5_state_s {
- md5_word_t count[2]; /* message length in bits, lsw first */
- md5_word_t abcd[4]; /* digest buffer */
- md5_byte_t buf[64]; /* accumulate block */
-} md5_state_t;
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/* Initialize the algorithm. */
-MD5_STATIC void md5_init(md5_state_t *pms);
-
-/* Append a string to the message. */
-MD5_STATIC void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
-
-/* Finish the message and return the digest. */
-MD5_STATIC void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-#endif /* md5_INCLUDED */
-
-/*
- Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- L. Peter Deutsch
- ghost@aladdin.com
-
- */
-/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
-/*
- Independent implementation of MD5 (RFC 1321).
-
- This code implements the MD5 Algorithm defined in RFC 1321, whose
- text is available at
- http://www.ietf.org/rfc/rfc1321.txt
- The code is derived from the text of the RFC, including the test suite
- (section A.5) but excluding the rest of Appendix A. It does not include
- any code or documentation that is identified in the RFC as being
- copyrighted.
-
- The original and principal author of md5.c is L. Peter Deutsch
- <gh...@aladdin.com>. Other authors are noted in the change history
- that follows (in reverse chronological order):
-
- 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
- either statically or dynamically; added missing #include <string.h>
- in library.
- 2002-03-11 lpd Corrected argument list for main(), and added int return
- type, in test program and T value program.
- 2002-02-21 lpd Added missing #include <stdio.h> in test program.
- 2000-07-03 lpd Patched to eliminate warnings about "constant is
- unsigned in ANSI C, signed in traditional"; made test program
- self-checking.
- 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
- 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
- 1999-05-03 lpd Original version.
- */
-
-#ifndef MD5_STATIC
-#include <string.h>
-#endif
-
-#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
-#ifdef ARCH_IS_BIG_ENDIAN
-# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
-#else
-# define BYTE_ORDER 0
-#endif
-
-#define T_MASK ((md5_word_t)~0)
-#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
-#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
-#define T3 0x242070db
-#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
-#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
-#define T6 0x4787c62a
-#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
-#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
-#define T9 0x698098d8
-#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
-#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
-#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
-#define T13 0x6b901122
-#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
-#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
-#define T16 0x49b40821
-#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
-#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
-#define T19 0x265e5a51
-#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
-#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
-#define T22 0x02441453
-#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
-#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
-#define T25 0x21e1cde6
-#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
-#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
-#define T28 0x455a14ed
-#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
-#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
-#define T31 0x676f02d9
-#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
-#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
-#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
-#define T35 0x6d9d6122
-#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
-#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
-#define T38 0x4bdecfa9
-#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
-#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
-#define T41 0x289b7ec6
-#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
-#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
-#define T44 0x04881d05
-#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
-#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
-#define T47 0x1fa27cf8
-#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
-#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
-#define T50 0x432aff97
-#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
-#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
-#define T53 0x655b59c3
-#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
-#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
-#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
-#define T57 0x6fa87e4f
-#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
-#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
-#define T60 0x4e0811a1
-#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
-#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
-#define T63 0x2ad7d2bb
-#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
-
-
-static void
-md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
-{
- md5_word_t
- a = pms->abcd[0], b = pms->abcd[1],
- c = pms->abcd[2], d = pms->abcd[3];
- md5_word_t t;
-#if BYTE_ORDER > 0
- /* Define storage only for big-endian CPUs. */
- md5_word_t X[16];
-#else
- /* Define storage for little-endian or both types of CPUs. */
- md5_word_t xbuf[16];
- const md5_word_t *X;
-#endif
-
- {
-#if BYTE_ORDER == 0
- /*
- * Determine dynamically whether this is a big-endian or
- * little-endian machine, since we can use a more efficient
- * algorithm on the latter.
- */
- static const int w = 1;
-
- if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
-#endif
-#if BYTE_ORDER <= 0 /* little-endian */
- {
- /*
- * On little-endian machines, we can process properly aligned
- * data without copying it.
- */
- if (!((data - (const md5_byte_t *)0) & 3)) {
- /* data are properly aligned */
- X = (const md5_word_t *)data;
- } else {
- /* not aligned */
- memcpy(xbuf, data, 64);
- X = xbuf;
- }
- }
-#endif
-#if BYTE_ORDER == 0
- else /* dynamic big-endian */
-#endif
-#if BYTE_ORDER >= 0 /* big-endian */
- {
- /*
- * On big-endian machines, we must arrange the bytes in the
- * right order.
- */
- const md5_byte_t *xp = data;
- int i;
-
-# if BYTE_ORDER == 0
- X = xbuf; /* (dynamic only) */
-# else
-# define xbuf X /* (static only) */
-# endif
- for (i = 0; i < 16; ++i, xp += 4)
- xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
- }
-#endif
- }
-
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
- /* Round 1. */
- /* Let [abcd k s i] denote the operation
- a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + F(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 7, T1);
- SET(d, a, b, c, 1, 12, T2);
- SET(c, d, a, b, 2, 17, T3);
- SET(b, c, d, a, 3, 22, T4);
- SET(a, b, c, d, 4, 7, T5);
- SET(d, a, b, c, 5, 12, T6);
- SET(c, d, a, b, 6, 17, T7);
- SET(b, c, d, a, 7, 22, T8);
- SET(a, b, c, d, 8, 7, T9);
- SET(d, a, b, c, 9, 12, T10);
- SET(c, d, a, b, 10, 17, T11);
- SET(b, c, d, a, 11, 22, T12);
- SET(a, b, c, d, 12, 7, T13);
- SET(d, a, b, c, 13, 12, T14);
- SET(c, d, a, b, 14, 17, T15);
- SET(b, c, d, a, 15, 22, T16);
-#undef SET
-
- /* Round 2. */
- /* Let [abcd k s i] denote the operation
- a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + G(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 1, 5, T17);
- SET(d, a, b, c, 6, 9, T18);
- SET(c, d, a, b, 11, 14, T19);
- SET(b, c, d, a, 0, 20, T20);
- SET(a, b, c, d, 5, 5, T21);
- SET(d, a, b, c, 10, 9, T22);
- SET(c, d, a, b, 15, 14, T23);
- SET(b, c, d, a, 4, 20, T24);
- SET(a, b, c, d, 9, 5, T25);
- SET(d, a, b, c, 14, 9, T26);
- SET(c, d, a, b, 3, 14, T27);
- SET(b, c, d, a, 8, 20, T28);
- SET(a, b, c, d, 13, 5, T29);
- SET(d, a, b, c, 2, 9, T30);
- SET(c, d, a, b, 7, 14, T31);
- SET(b, c, d, a, 12, 20, T32);
-#undef SET
-
- /* Round 3. */
- /* Let [abcd k s t] denote the operation
- a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + H(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 5, 4, T33);
- SET(d, a, b, c, 8, 11, T34);
- SET(c, d, a, b, 11, 16, T35);
- SET(b, c, d, a, 14, 23, T36);
- SET(a, b, c, d, 1, 4, T37);
- SET(d, a, b, c, 4, 11, T38);
- SET(c, d, a, b, 7, 16, T39);
- SET(b, c, d, a, 10, 23, T40);
- SET(a, b, c, d, 13, 4, T41);
- SET(d, a, b, c, 0, 11, T42);
- SET(c, d, a, b, 3, 16, T43);
- SET(b, c, d, a, 6, 23, T44);
- SET(a, b, c, d, 9, 4, T45);
- SET(d, a, b, c, 12, 11, T46);
- SET(c, d, a, b, 15, 16, T47);
- SET(b, c, d, a, 2, 23, T48);
-#undef SET
-
- /* Round 4. */
- /* Let [abcd k s t] denote the operation
- a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + I(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 6, T49);
- SET(d, a, b, c, 7, 10, T50);
- SET(c, d, a, b, 14, 15, T51);
- SET(b, c, d, a, 5, 21, T52);
- SET(a, b, c, d, 12, 6, T53);
- SET(d, a, b, c, 3, 10, T54);
- SET(c, d, a, b, 10, 15, T55);
- SET(b, c, d, a, 1, 21, T56);
- SET(a, b, c, d, 8, 6, T57);
- SET(d, a, b, c, 15, 10, T58);
- SET(c, d, a, b, 6, 15, T59);
- SET(b, c, d, a, 13, 21, T60);
- SET(a, b, c, d, 4, 6, T61);
- SET(d, a, b, c, 11, 10, T62);
- SET(c, d, a, b, 2, 15, T63);
- SET(b, c, d, a, 9, 21, T64);
-#undef SET
-
- /* Then perform the following additions. (That is increment each
- of the four registers by the value it had before this block
- was started.) */
- pms->abcd[0] += a;
- pms->abcd[1] += b;
- pms->abcd[2] += c;
- pms->abcd[3] += d;
-}
-
-MD5_STATIC void
-md5_init(md5_state_t *pms)
-{
- pms->count[0] = pms->count[1] = 0;
- pms->abcd[0] = 0x67452301;
- pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
- pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
- pms->abcd[3] = 0x10325476;
-}
-
-MD5_STATIC void
-md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
-{
- const md5_byte_t *p = data;
- int left = nbytes;
- int offset = (pms->count[0] >> 3) & 63;
- md5_word_t nbits = (md5_word_t)(nbytes << 3);
-
- if (nbytes <= 0)
- return;
-
- /* Update the message length. */
- pms->count[1] += nbytes >> 29;
- pms->count[0] += nbits;
- if (pms->count[0] < nbits)
- pms->count[1]++;
-
- /* Process an initial partial block. */
- if (offset) {
- int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
- memcpy(pms->buf + offset, p, copy);
- if (offset + copy < 64)
- return;
- p += copy;
- left -= copy;
- md5_process(pms, pms->buf);
- }
-
- /* Process full blocks. */
- for (; left >= 64; p += 64, left -= 64)
- md5_process(pms, p);
-
- /* Process a final partial block. */
- if (left)
- memcpy(pms->buf, p, left);
-}
-
-MD5_STATIC void
-md5_finish(md5_state_t *pms, md5_byte_t digest[16])
-{
- static const md5_byte_t pad[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- md5_byte_t data[8];
- int i;
-
- /* Save the length before padding. */
- for (i = 0; i < 8; ++i)
- data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
- /* Pad to 56 bytes mod 64. */
- md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
- /* Append the length. */
- md5_append(pms, data, 8);
- for (i = 0; i < 16; ++i)
- digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_configured/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/CMakeLists.txt b/remote_services/discovery_configured/CMakeLists.txt
index e0f3e9b..f7d104b 100644
--- a/remote_services/discovery_configured/CMakeLists.txt
+++ b/remote_services/discovery_configured/CMakeLists.txt
@@ -25,9 +25,15 @@ if (RSA_DISCOVERY_CONFIGURED)
NAME "Apache Celix RSA Configured Discovery"
SOURCES
src/discovery_impl.c
+ $<TARGET_OBJECTS:discovery_common>
+ $<TARGET_OBJECTS:civetweb>
)
- target_include_directories(discovery_configured PRIVATE src)
- target_link_libraries(discovery_configured PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} Celix::log_helper discovery_common)
+ target_include_directories(discovery_configured PRIVATE
+ src
+ $<TARGET_PROPERTY:discovery_common,INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>
+ )
+ target_link_libraries(discovery_configured PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} Celix::log_helper)
install_bundle(discovery_configured)
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_configured/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/src/discovery_impl.c b/remote_services/discovery_configured/src/discovery_impl.c
index 35a0c71..89c777e 100644
--- a/remote_services/discovery_configured/src/discovery_impl.c
+++ b/remote_services/discovery_configured/src/discovery_impl.c
@@ -66,12 +66,12 @@ celix_status_t discovery_start(discovery_pt discovery) {
logHelper_start(discovery->loghelper);
- status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
+ status = endpointDiscoveryPoller_create(discovery, discovery->context, DEFAULT_POLL_ENDPOINTS, &discovery->poller);
if (status != CELIX_SUCCESS) {
return CELIX_BUNDLE_EXCEPTION;
}
- status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
+ status = endpointDiscoveryServer_create(discovery, discovery->context, DEFAULT_SERVER_PATH, DEFAULT_SERVER_PORT, DEFAULT_SERVER_IP, &discovery->server);
if (status != CELIX_SUCCESS) {
return CELIX_BUNDLE_EXCEPTION;
}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_configured/src/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_configured/src/discovery_impl.h b/remote_services/discovery_configured/src/discovery_impl.h
index 0414eac..a9d56c1 100644
--- a/remote_services/discovery_configured/src/discovery_impl.h
+++ b/remote_services/discovery_configured/src/discovery_impl.h
@@ -44,19 +44,19 @@
#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.configured"
-struct discovery {
- bundle_context_pt context;
-
- celix_thread_mutex_t listenerReferencesMutex;
- celix_thread_mutex_t discoveredServicesMutex;
-
- hash_map_pt listenerReferences; //key=serviceReference, value=nop
- hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
-
- endpoint_discovery_poller_pt poller;
- endpoint_discovery_server_pt server;
-
- log_helper_pt loghelper;
-};
+//struct discovery_impl {
+// bundle_context_pt context;
+//
+// celix_thread_mutex_t listenerReferencesMutex;
+// celix_thread_mutex_t discoveredServicesMutex;
+//
+// hash_map_pt listenerReferences; //key=serviceReference, value=nop
+// hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
+//
+// endpoint_discovery_poller_pt poller;
+// endpoint_discovery_server_pt server;
+//
+// log_helper_pt loghelper;
+//};
#endif /* DISCOVERY_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_etcd/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_etcd/CMakeLists.txt b/remote_services/discovery_etcd/CMakeLists.txt
index 4168281..9c8edc8 100644
--- a/remote_services/discovery_etcd/CMakeLists.txt
+++ b/remote_services/discovery_etcd/CMakeLists.txt
@@ -28,11 +28,19 @@ if (RSA_DISCOVERY_ETCD)
SOURCES
src/discovery_impl.c
src/etcd_watcher.c
+ $<TARGET_OBJECTS:discovery_common>
+ $<TARGET_OBJECTS:civetweb>
)
- target_link_libraries(discovery_etcd PRIVATE Celix::log_helper)
- target_include_directories(discovery_etcd PRIVATE src )
- target_include_directories(discovery_etcd PRIVATE ${CURL_INCLUDE_DIR} ${JANSSON_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
- target_link_libraries(discovery_etcd PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} ${JANSSON_LIBRARIES} discovery_common)
+ target_link_libraries(discovery_etcd PRIVATE Celix::log_helper Celix::etcdlib_static)
+ target_include_directories(discovery_etcd PRIVATE src)
+ target_include_directories(discovery_etcd PRIVATE
+ $<TARGET_PROPERTY:discovery_common,INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>
+ ${CURL_INCLUDE_DIR}
+ ${JANSSON_INCLUDE_DIR}
+ ${LIBXML2_INCLUDE_DIR}
+ )
+ target_link_libraries(discovery_etcd PRIVATE ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} ${JANSSON_LIBRARIES})
install_bundle(discovery_etcd)
endif (RSA_DISCOVERY_ETCD)
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_etcd/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_etcd/src/discovery_impl.c b/remote_services/discovery_etcd/src/discovery_impl.c
index 8087d95..500399e 100644
--- a/remote_services/discovery_etcd/src/discovery_impl.c
+++ b/remote_services/discovery_etcd/src/discovery_impl.c
@@ -50,25 +50,35 @@
-celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery) {
+celix_status_t discovery_create(bundle_context_pt context, discovery_t** out) {
celix_status_t status = CELIX_SUCCESS;
- *discovery = malloc(sizeof(struct discovery));
- if (!*discovery) {
- return CELIX_ENOMEM;
- }
+ discovery_t* discovery = calloc(1, sizeof(*discovery));
+ discovery_impl_t* pImpl = calloc(1, sizeof(*pImpl));
+
+ if (discovery != NULL && pImpl != NULL) {
+ discovery->pImpl = pImpl;
+ discovery->context = context;
+ discovery->poller = NULL;
+ discovery->server = NULL;
- (*discovery)->context = context;
- (*discovery)->poller = NULL;
- (*discovery)->server = NULL;
+ discovery->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2,
+ NULL);
+ discovery->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
- (*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
- (*discovery)->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+ status = celixThreadMutex_create(&discovery->listenerReferencesMutex, NULL);
+ status = celixThreadMutex_create(&discovery->discoveredServicesMutex, NULL);
- status = celixThreadMutex_create(&(*discovery)->listenerReferencesMutex, NULL);
- status = celixThreadMutex_create(&(*discovery)->discoveredServicesMutex, NULL);
+ logHelper_create(context, &discovery->loghelper);
+ } else {
+ status = CELIX_ENOMEM;
+ free(discovery);
+ free(pImpl);
+ }
- logHelper_create(context, &(*discovery)->loghelper);
+ if (status == CELIX_SUCCESS) {
+ *out = discovery;
+ }
return status;
}
@@ -124,17 +134,17 @@ celix_status_t discovery_start(discovery_pt discovery) {
path = DEFAULT_SERVER_PATH;
}
- status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
+ status = endpointDiscoveryPoller_create(discovery, discovery->context, DEFAULT_POLL_ENDPOINTS, &discovery->poller);
if (status != CELIX_SUCCESS) {
return CELIX_BUNDLE_EXCEPTION;
}
- status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
+ status = endpointDiscoveryServer_create(discovery, discovery->context, DEFAULT_SERVER_PATH, DEFAULT_SERVER_PORT, DEFAULT_SERVER_IP, &discovery->server);
if (status != CELIX_SUCCESS) {
return CELIX_BUNDLE_EXCEPTION;
}
- status = etcdWatcher_create(discovery, discovery->context, &discovery->watcher);
+ status = etcdWatcher_create(discovery, discovery->context, &discovery->pImpl->watcher);
if (status != CELIX_SUCCESS) {
return CELIX_BUNDLE_EXCEPTION;
}
@@ -144,7 +154,7 @@ celix_status_t discovery_start(discovery_pt discovery) {
celix_status_t discovery_stop(discovery_pt discovery) {
celix_status_t status;
- status = etcdWatcher_destroy(discovery->watcher);
+ status = etcdWatcher_destroy(discovery->pImpl->watcher);
if (status != CELIX_SUCCESS) {
return CELIX_BUNDLE_EXCEPTION;
}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_etcd/src/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_etcd/src/discovery_impl.h b/remote_services/discovery_etcd/src/discovery_impl.h
index a19b145..f28017b 100644
--- a/remote_services/discovery_etcd/src/discovery_impl.h
+++ b/remote_services/discovery_etcd/src/discovery_impl.h
@@ -47,20 +47,8 @@
#define FREE_MEM(ptr) if(ptr) {free(ptr); ptr = NULL;}
-struct discovery {
- bundle_context_pt context;
-
- celix_thread_mutex_t listenerReferencesMutex;
- celix_thread_mutex_t discoveredServicesMutex;
-
- hash_map_pt listenerReferences; //key=serviceReference, value=nop
- hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
-
- etcd_watcher_pt watcher;
- endpoint_discovery_poller_pt poller;
- endpoint_discovery_server_pt server;
-
- log_helper_pt loghelper;
+struct discovery_impl {
+ etcd_watcher_t* watcher;
};
#endif /* DISCOVERY_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_etcd/src/etcd_watcher.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_etcd/src/etcd_watcher.h b/remote_services/discovery_etcd/src/etcd_watcher.h
index b4dbf40..56bae92 100644
--- a/remote_services/discovery_etcd/src/etcd_watcher.h
+++ b/remote_services/discovery_etcd/src/etcd_watcher.h
@@ -31,6 +31,7 @@
#include "discovery.h"
#include "endpoint_discovery_poller.h"
+typedef struct etcd_watcher etcd_watcher_t;
typedef struct etcd_watcher *etcd_watcher_pt;
celix_status_t etcdWatcher_create(discovery_pt discovery, bundle_context_pt context, etcd_watcher_pt *watcher);
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_shm/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/CMakeLists.txt b/remote_services/discovery_shm/CMakeLists.txt
index dff403d..61e54f7 100644
--- a/remote_services/discovery_shm/CMakeLists.txt
+++ b/remote_services/discovery_shm/CMakeLists.txt
@@ -28,13 +28,17 @@ find_package(CURL REQUIRED)
src/discovery_shm.c
src/discovery_shmWatcher.c
src/discovery_impl.c
+ $<TARGET_OBJECTS:discovery_common>
+ $<TARGET_OBJECTS:civetweb>
)
target_include_directories(discovery_shm PRIVATE
src
${LIBXML2_INCLUDE_DIR}
${CURL_INCLUDE_DIR}
+ $<TARGET_PROPERTY:discovery_common,INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>
)
- target_link_libraries(discovery_shm PRIVATE Celix::framework ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES} discovery_common)
+ target_link_libraries(discovery_shm PRIVATE Celix::framework ${CURL_LIBRARIES} ${LIBXML2_LIBRARIES})
install_bundle(discovery_shm)
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_shm/src/discovery_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_impl.c b/remote_services/discovery_shm/src/discovery_impl.c
index 2604595..fadff8c 100644
--- a/remote_services/discovery_shm/src/discovery_impl.c
+++ b/remote_services/discovery_shm/src/discovery_impl.c
@@ -48,28 +48,34 @@
#include "endpoint_discovery_poller.h"
#include "endpoint_discovery_server.h"
-
-
-celix_status_t discovery_create(bundle_context_pt context, discovery_pt *discovery) {
+celix_status_t discovery_create(bundle_context_pt context, discovery_t** out) {
celix_status_t status = CELIX_SUCCESS;
- *discovery = calloc(1, sizeof(struct discovery));
- if (!*discovery) {
- status = CELIX_ENOMEM;
- } else {
- (*discovery)->context = context;
- (*discovery)->poller = NULL;
- (*discovery)->server = NULL;
+ discovery_t* discovery = calloc(1, sizeof(*discovery));
+ discovery_impl_t* pImpl = calloc(1, sizeof(*pImpl));
+ if (discovery != NULL && pImpl != NULL) {
+ discovery->pImpl = pImpl;
+ discovery->context = context;
+ discovery->poller = NULL;
+ discovery->server = NULL;
- (*discovery)->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
- (*discovery)->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+ discovery->listenerReferences = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL);
+ discovery->discoveredServices = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
- celixThreadMutex_create(&(*discovery)->listenerReferencesMutex, NULL);
- celixThreadMutex_create(&(*discovery)->discoveredServicesMutex, NULL);
+ celixThreadMutex_create(&discovery->listenerReferencesMutex, NULL);
+ celixThreadMutex_create(&discovery->discoveredServicesMutex, NULL);
- if (logHelper_create(context, &(*discovery)->loghelper) == CELIX_SUCCESS) {
- logHelper_start((*discovery)->loghelper);
+ if (logHelper_create(context, &discovery->loghelper) == CELIX_SUCCESS) {
+ logHelper_start(discovery->loghelper);
}
+ } else {
+ status = CELIX_ENOMEM;
+ free(discovery);
+ free(pImpl);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ *out = discovery;
}
return status;
@@ -113,9 +119,9 @@ celix_status_t discovery_destroy(discovery_pt discovery) {
celix_status_t discovery_start(discovery_pt discovery) {
celix_status_t status;
- status = endpointDiscoveryPoller_create(discovery, discovery->context, &discovery->poller);
+ status = endpointDiscoveryPoller_create(discovery, discovery->context, DEFAULT_POLL_ENDPOINTS, &discovery->poller);
if (status == CELIX_SUCCESS) {
- status = endpointDiscoveryServer_create(discovery, discovery->context, &discovery->server);
+ status = endpointDiscoveryServer_create(discovery, discovery->context, DEFAULT_SERVER_PATH, DEFAULT_SERVER_PORT, DEFAULT_SERVER_IP, &discovery->server);
}
if (status == CELIX_SUCCESS) {
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_shm/src/discovery_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_impl.h b/remote_services/discovery_shm/src/discovery_impl.h
index c7206bd..e994b1f 100644
--- a/remote_services/discovery_shm/src/discovery_impl.h
+++ b/remote_services/discovery_shm/src/discovery_impl.h
@@ -37,30 +37,17 @@
#include "endpoint_discovery_server.h"
#include "discovery_shmWatcher.h"
-
#define DEFAULT_SERVER_IP "127.0.0.1"
#define DEFAULT_SERVER_PORT "9999"
#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.shm"
#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.shm"
-#define MAX_ROOTNODE_LENGTH 64
-#define MAX_LOCALNODE_LENGTH 256
-
-
-struct discovery {
- bundle_context_pt context;
-
- celix_thread_mutex_t listenerReferencesMutex;
- celix_thread_mutex_t discoveredServicesMutex;
-
- hash_map_pt listenerReferences; //key=serviceReference, value=nop
- hash_map_pt discoveredServices; //key=endpointId (string), value=endpoint_description_pt
+#define MAX_ROOTNODE_LENGTH 64
+#define MAX_LOCALNODE_LENGTH 256
- shm_watcher_pt watcher;
- endpoint_discovery_poller_pt poller;
- endpoint_discovery_server_pt server;
- log_helper_pt loghelper;
+struct discovery_impl {
+ shm_watcher_t* watcher;
};
#endif /* DISCOVERY_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_shm/src/discovery_shmWatcher.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_shmWatcher.c b/remote_services/discovery_shm/src/discovery_shmWatcher.c
index 6460de8..ef7df71 100644
--- a/remote_services/discovery_shm/src/discovery_shmWatcher.c
+++ b/remote_services/discovery_shm/src/discovery_shmWatcher.c
@@ -40,6 +40,15 @@
#include "endpoint_discovery_poller.h"
+#define DEFAULT_SERVER_IP "127.0.0.1"
+#define DEFAULT_SERVER_PORT "9999"
+#define DEFAULT_SERVER_PATH "/org.apache.celix.discovery.shm"
+#define DEFAULT_POLL_ENDPOINTS "http://localhost:9999/org.apache.celix.discovery.shm"
+
+#define MAX_ROOTNODE_LENGTH 64
+#define MAX_LOCALNODE_LENGTH 256
+
+
struct shm_watcher {
shmData_pt shmData;
celix_thread_t watcherThread;
@@ -82,7 +91,7 @@ static celix_status_t discoveryShmWatcher_getLocalNodePath(bundle_context_pt con
/* retrieves all endpoints from shm and syncs them with the ones already available */
static celix_status_t discoveryShmWatcher_syncEndpoints(discovery_pt discovery) {
celix_status_t status = CELIX_SUCCESS;
- shm_watcher_pt watcher = discovery->watcher;
+ shm_watcher_pt watcher = discovery->pImpl->watcher;
char** shmKeyArr = calloc(SHM_DATA_MAX_ENTRIES, sizeof(*shmKeyArr));
array_list_pt registeredKeyArr = NULL;
@@ -147,7 +156,7 @@ static celix_status_t discoveryShmWatcher_syncEndpoints(discovery_pt discovery)
static void* discoveryShmWatcher_run(void* data) {
discovery_pt discovery = (discovery_pt) data;
- shm_watcher_pt watcher = discovery->watcher;
+ shm_watcher_pt watcher = discovery->pImpl->watcher;
char localNodePath[MAX_LOCALNODE_LENGTH];
char url[MAX_LOCALNODE_LENGTH];
@@ -194,10 +203,10 @@ celix_status_t discoveryShmWatcher_create(discovery_pt discovery) {
}
if (status == CELIX_SUCCESS) {
- discovery->watcher = watcher;
+ discovery->pImpl->watcher = watcher;
}
else{
- discovery->watcher = NULL;
+ discovery->pImpl->watcher = NULL;
free(watcher);
}
@@ -216,7 +225,7 @@ celix_status_t discoveryShmWatcher_create(discovery_pt discovery) {
celix_status_t discoveryShmWatcher_destroy(discovery_pt discovery) {
celix_status_t status;
- shm_watcher_pt watcher = discovery->watcher;
+ shm_watcher_pt watcher = discovery->pImpl->watcher;
char localNodePath[MAX_LOCALNODE_LENGTH];
celixThreadMutex_lock(&watcher->watcherLock);
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_shm/src/discovery_shmWatcher.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_shm/src/discovery_shmWatcher.h b/remote_services/discovery_shm/src/discovery_shmWatcher.h
index ff70f72..4e7e1d5 100644
--- a/remote_services/discovery_shm/src/discovery_shmWatcher.h
+++ b/remote_services/discovery_shm/src/discovery_shmWatcher.h
@@ -31,6 +31,7 @@
#include "discovery.h"
#include "endpoint_discovery_poller.h"
+typedef struct shm_watcher shm_watcher_t;
typedef struct shm_watcher *shm_watcher_pt;
celix_status_t discoveryShmWatcher_create(discovery_pt discovery);
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_common/CMakeLists.txt b/remote_services/remote_service_admin_common/CMakeLists.txt
index 1813211..a421cda 100644
--- a/remote_services/remote_service_admin_common/CMakeLists.txt
+++ b/remote_services/remote_service_admin_common/CMakeLists.txt
@@ -21,4 +21,6 @@ add_library(remote_service_admin_common STATIC
src/import_registration_impl.c
)
target_include_directories(remote_service_admin_common PRIVATE src)
-target_link_libraries(remote_service_admin_common PUBLIC Celix::framework Celix::remote_service_admin_api Celix::log_helper)
\ No newline at end of file
+target_link_libraries(remote_service_admin_common PUBLIC Celix::framework Celix::remote_service_admin_api Celix::log_helper)
+
+add_library(Celix::remote_service_admin_common ALIAS remote_service_admin_common)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/CMakeLists.txt b/remote_services/remote_service_admin_dfi/CMakeLists.txt
index 4b28231..206c6dc 100644
--- a/remote_services/remote_service_admin_dfi/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/CMakeLists.txt
@@ -23,21 +23,31 @@ if (RSA_REMOTE_SERVICE_ADMIN_DFI)
find_package(CURL REQUIRED)
find_package(Jansson REQUIRED)
- include_directories(
- ${CURL_INCLUDE_DIRS}
- ${JANSSON_INCLUDE_DIRS}
+ add_bundle(remote_service_admin_dfi
+ VERSION 0.9.0
+ SYMBOLIC_NAME "apache_celix_remote_service_admin_dfi"
+ NAME "Apache Celix Remote Service Admin Dynamic Function Interface (DFI)"
+ SOURCES
+ src/remote_service_admin_dfi.c
+ src/remote_service_admin_activator.c
+ src/export_registration_dfi.c
+ src/import_registration_dfi.c
+ src/dfi_utils.c
+ $<TARGET_OBJECTS:civetweb>
)
+ target_include_directories(remote_service_admin_dfi PRIVATE src $<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>)
+ target_link_libraries(remote_service_admin_dfi PRIVATE
+ Celix::dfi_static
+ Celix::log_helper
+ Celix::remote_service_admin_common
+ ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
- if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
- include_directories(dynamic_function_interface/memstream)
- endif()
-
- add_subdirectory(rsa)
+ install_bundle(remote_service_admin_dfi)
if (ENABLE_TESTING)
- find_package(CppUTest REQUIRED)
- include_directories(${CPPUTEST_INCLUDE_DIR})
- add_subdirectory(rsa_tst)
+ add_subdirectory(test)
endif()
+ #Setup target aliases to match external usage
+ add_library(Celix::remote_service_admin_dfi ALIAS remote_service_admin_dfi)
endif()
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
deleted file mode 100644
index 3efabf8..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/CMakeLists.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-add_bundle(remote_service_admin_dfi
- VERSION 0.9.0
- SYMBOLIC_NAME "apache_celix_remote_service_admin_dfi"
- NAME "Apache Celix Remote Service Admin Dynamic Function Interface (DFI)"
- SOURCES
- src/remote_service_admin_dfi.c
- src/remote_service_admin_activator.c
- src/export_registration_dfi.c
- src/import_registration_dfi.c
- src/dfi_utils.c
-)
-target_include_directories(remote_service_admin_dfi PRIVATE src)
-target_link_libraries(remote_service_admin_dfi PRIVATE
- Celix::dfi Celix::log_helper remote_service_admin_common
- ${CURL_LIBRARIES} ${JANSSON_LIBRARIES})
-
-install_bundle(remote_service_admin_dfi)
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c b/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c
deleted file mode 100644
index 1b1eb36..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include "dfi_utils.h"
-#include <stdlib.h>
-#include <unistd.h>
-
-static celix_status_t dfi_findFileForFramework(bundle_context_pt context, const char *fileName, FILE **out) {
- celix_status_t status;
-
- char pwd[1024];
- char path[1024];
- const char *extPath = NULL;
-
- status = bundleContext_getProperty(context, "CELIX_FRAMEWORK_EXTENDER_PATH", &extPath);
- if (status != CELIX_SUCCESS || extPath == NULL) {
- getcwd(pwd, sizeof(pwd));
- extPath = pwd;
- }
-
- snprintf(path, sizeof(path), "%s/%s", extPath, fileName);
-
- if (status == CELIX_SUCCESS) {
- FILE *df = fopen(path, "r");
- if (df == NULL) {
- status = CELIX_FILE_IO_EXCEPTION;
- } else {
- *out = df;
- }
- }
-
- return status;
-}
-
-static celix_status_t dfi_findFileForBundle(bundle_pt bundle, const char *fileName, FILE **out) {
- celix_status_t status;
-
- char *path = NULL;
- char metaInfFileName[512];
- snprintf(metaInfFileName, sizeof(metaInfFileName), "META-INF/descriptors/%s", fileName);
-
- status = bundle_getEntry(bundle, fileName, &path);
-
- if (status != CELIX_SUCCESS || path == NULL) {
- status = bundle_getEntry(bundle, metaInfFileName, &path);
- }
-
- if (status == CELIX_SUCCESS && path != NULL) {
- FILE *df = fopen(path, "r");
- if (df == NULL) {
- status = CELIX_FILE_IO_EXCEPTION;
- } else {
- *out = df;
- }
-
- }
-
- free(path);
- return status;
-}
-
-celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out) {
- celix_status_t status;
- char fileName[128];
-
- snprintf(fileName, 128, "%s.descriptor", name);
-
- long id;
- status = bundle_getBundleId(bundle, &id);
-
- if (status == CELIX_SUCCESS) {
- if (id == 0) {
- //framework bundle
- status = dfi_findFileForFramework(context, fileName, out);
- } else {
- //normal bundle
- status = dfi_findFileForBundle(bundle, fileName, out);
- }
- }
-
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h b/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h
deleted file mode 100644
index cec8aa1..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/src/dfi_utils.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-#ifndef DFI_UTILS_H_
-#define DFI_UTILS_H_
-
-#include "bundle.h"
-#include "bundle_context.h"
-#include <stdio.h>
-#include "celix_errno.h"
-
-
-celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out);
-
-#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c
deleted file mode 100644
index b83b5a8..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <jansson.h>
-#include <dyn_interface.h>
-#include <json_serializer.h>
-#include <remote_constants.h>
-#include <remote_service_admin.h>
-#include <service_tracker_customizer.h>
-#include <service_tracker.h>
-#include <json_rpc.h>
-#include "constants.h"
-#include "export_registration_dfi.h"
-#include "dfi_utils.h"
-
-struct export_reference {
- endpoint_description_pt endpoint; //owner
- service_reference_pt reference;
-};
-
-struct export_registration {
- bundle_context_pt context;
- struct export_reference exportReference;
- char *servId;
- dyn_interface_type *intf; //owner
- service_tracker_pt tracker;
-
- celix_thread_mutex_t mutex;
- void *service; //protected by mutex
-
- //TODO add tracker and lock
- bool closed;
-};
-
-static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service);
-static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service);
-
-celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *out) {
- celix_status_t status = CELIX_SUCCESS;
-
- const char *servId = NULL;
- status = serviceReference_getProperty(reference, "service.id", &servId);
- if (status != CELIX_SUCCESS) {
- logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Cannot find service.id for ref");
- }
-
- export_registration_pt reg = NULL;
- if (status == CELIX_SUCCESS) {
- reg = calloc(1, sizeof(*reg));
- if (reg == NULL) {
- status = CELIX_ENOMEM;
- }
- }
-
-
- if (status == CELIX_SUCCESS) {
- reg->context = context;
- reg->exportReference.endpoint = endpoint;
- reg->exportReference.reference = reference;
- reg->closed = false;
-
- celixThreadMutex_create(®->mutex, NULL);
- }
-
- const char *exports = NULL;
- CELIX_DO_IF(status, serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports));
-
- bundle_pt bundle = NULL;
- CELIX_DO_IF(status, serviceReference_getBundle(reference, &bundle));
-
- FILE *descriptor = NULL;
- if (status == CELIX_SUCCESS) {
- status = dfi_findDescriptor(context, bundle, exports, &descriptor);
- }
-
- if (status != CELIX_SUCCESS || descriptor == NULL) {
- status = CELIX_BUNDLE_EXCEPTION;
- logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", exports);
- }
-
- if (status == CELIX_SUCCESS) {
- int rc = dynInterface_parse(descriptor, ®->intf);
- fclose(descriptor);
- if (rc != 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "RSA: Error parsing service descriptor.");
- }
- else{
- /* Add the interface version as a property in the properties_map */
- char* intfVersion = NULL;
- dynInterface_getVersionString(reg->intf, &intfVersion);
- const char *serviceVersion = properties_get(endpoint->properties,(char*) CELIX_FRAMEWORK_SERVICE_VERSION);
- if(serviceVersion!=NULL){
- if(strcmp(serviceVersion,intfVersion)!=0){
- logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Service version (%s) and interface version from the descriptor (%s) are not the same!",serviceVersion,intfVersion);
- }
- }
- else{
- properties_set(endpoint->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION, intfVersion);
- }
- }
- }
-
- if (status == CELIX_SUCCESS) {
- service_tracker_customizer_pt cust = NULL;
- status = serviceTrackerCustomizer_create(reg, NULL, (void *) exportRegistration_addServ, NULL,
- (void *) exportRegistration_removeServ, &cust);
- if (status == CELIX_SUCCESS) {
- char filter[32];
- snprintf(filter, 32, "(service.id=%s)", servId);
- status = serviceTracker_createWithFilter(reg->context, filter, cust, ®->tracker);
- }
- }
-
- if (status == CELIX_SUCCESS) {
- *out = reg;
- } else {
- logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Error creating export registration");
- exportRegistration_destroy(reg);
- }
-
- return status;
-}
-
-celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **responseOut, int *responseLength) {
- int status = CELIX_SUCCESS;
-
- //printf("calling for '%s'\n");
-
- *responseLength = -1;
- celixThreadMutex_lock(&export->mutex);
- status = jsonRpc_call(export->intf, export->service, data, responseOut);
- celixThreadMutex_unlock(&export->mutex);
-
- return status;
-}
-
-void exportRegistration_destroy(export_registration_pt reg) {
- if (reg != NULL) {
- if (reg->intf != NULL) {
- dyn_interface_type *intf = reg->intf;
- reg->intf = NULL;
- dynInterface_destroy(intf);
- }
-
- if (reg->exportReference.endpoint != NULL) {
- endpoint_description_pt ep = reg->exportReference.endpoint;
- reg->exportReference.endpoint = NULL;
- endpointDescription_destroy(ep);
- }
- if (reg->tracker != NULL) {
- serviceTracker_destroy(reg->tracker);
- }
- celixThreadMutex_destroy(®->mutex);
-
- free(reg);
- }
-}
-
-celix_status_t exportRegistration_start(export_registration_pt reg) {
- celix_status_t status = CELIX_SUCCESS;
-
- serviceTracker_open(reg->tracker);
- return status;
-}
-
-
-celix_status_t exportRegistration_stop(export_registration_pt reg) {
- celix_status_t status = CELIX_SUCCESS;
- if (status == CELIX_SUCCESS) {
- status = bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference);
- serviceTracker_close(reg->tracker);
- }
- return status;
-}
-
-static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service) {
- celixThreadMutex_lock(®->mutex);
- reg->service = service;
- celixThreadMutex_unlock(®->mutex);
-}
-
-static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service) {
- celixThreadMutex_lock(®->mutex);
- if (reg->service == service) {
- reg->service = NULL;
- }
- celixThreadMutex_unlock(®->mutex);
-}
-
-
-celix_status_t exportRegistration_close(export_registration_pt reg) {
- celix_status_t status = CELIX_SUCCESS;
- exportRegistration_stop(reg);
- return status;
-}
-
-
-celix_status_t exportRegistration_getException(export_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
- //TODO
- return status;
-}
-
-celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *out) {
- celix_status_t status = CELIX_SUCCESS;
- export_reference_pt ref = calloc(1, sizeof(*ref));
- if (ref != NULL) {
- ref->endpoint = registration->exportReference.endpoint;
- ref->reference = registration->exportReference.reference;
- } else {
- status = CELIX_ENOMEM;
- }
-
- if (status == CELIX_SUCCESS) {
- *out = ref;
- }
-
- return status;
-}
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
- celix_status_t status = CELIX_SUCCESS;
- *endpoint = reference->endpoint;
- return status;
-}
-
-celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *ref) {
- celix_status_t status = CELIX_SUCCESS;
- *ref = reference->reference;
- return status;
-}
-
-
-
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h b/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h
deleted file mode 100644
index 93f37ba..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/src/export_registration_dfi.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#ifndef CELIX_EXPORT_REGISTRATION_DFI_H
-#define CELIX_EXPORT_REGISTRATION_DFI_H
-
-
-#include "export_registration.h"
-#include "log_helper.h"
-#include "endpoint_description.h"
-
-celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *registration);
-celix_status_t exportRegistration_close(export_registration_pt registration);
-void exportRegistration_destroy(export_registration_pt registration);
-
-celix_status_t exportRegistration_start(export_registration_pt registration);
-celix_status_t exportRegistration_stop(export_registration_pt registration);
-
-celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **response, int *responseLength);
-
-
-#endif //CELIX_EXPORT_REGISTRATION_DFI_H
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c b/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c
deleted file mode 100644
index 0b8dcf7..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <stdlib.h>
-#include <jansson.h>
-#include <json_rpc.h>
-#include <assert.h>
-#include "version.h"
-#include "json_serializer.h"
-#include "dyn_interface.h"
-#include "import_registration.h"
-#include "import_registration_dfi.h"
-
-struct import_registration {
- bundle_context_pt context;
- endpoint_description_pt endpoint; //TODO owner? -> free when destroyed
- const char *classObject; //NOTE owned by endpoint
- version_pt version;
-
- celix_thread_mutex_t mutex; //protects send & sendhandle
- send_func_type send;
- void *sendHandle;
-
- service_factory_pt factory;
- service_registration_pt factoryReg;
-
- hash_map_pt proxies; //key -> bundle, value -> service_proxy
- celix_thread_mutex_t proxiesMutex; //protects proxies
-};
-
-struct service_proxy {
- dyn_interface_type *intf;
- void *service;
- size_t count;
-};
-
-static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle,
- struct service_proxy **proxy);
-static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal);
-static void importRegistration_destroyProxy(struct service_proxy *proxy);
-static void importRegistration_clearProxies(import_registration_pt import);
-
-celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt endpoint, const char *classObject, const char* serviceVersion,
- import_registration_pt *out) {
- celix_status_t status = CELIX_SUCCESS;
- import_registration_pt reg = calloc(1, sizeof(*reg));
-
- if (reg != NULL) {
- reg->factory = calloc(1, sizeof(*reg->factory));
- }
-
- if (reg != NULL && reg->factory != NULL) {
- reg->context = context;
- reg->endpoint = endpoint;
- reg->classObject = classObject;
- reg->proxies = hashMap_create(NULL, NULL, NULL, NULL);
-
- celixThreadMutex_create(®->mutex, NULL);
- celixThreadMutex_create(®->proxiesMutex, NULL);
- status = version_createVersionFromString((char*)serviceVersion,&(reg->version));
-
- reg->factory->handle = reg;
- reg->factory->getService = (void *)importRegistration_getService;
- reg->factory->ungetService = (void *)importRegistration_ungetService;
- } else {
- status = CELIX_ENOMEM;
- }
-
- if (status == CELIX_SUCCESS) {
- //printf("IMPORT REGISTRATION IS %p\n", reg);
- *out = reg;
- }
- else{
- importRegistration_destroy(reg);
- }
-
- return status;
-}
-
-
-celix_status_t importRegistration_setSendFn(import_registration_pt reg,
- send_func_type send,
- void *handle) {
- celixThreadMutex_lock(®->mutex);
- reg->send = send;
- reg->sendHandle = handle;
- celixThreadMutex_unlock(®->mutex);
-
- return CELIX_SUCCESS;
-}
-
-static void importRegistration_clearProxies(import_registration_pt import) {
- if (import != NULL) {
- pthread_mutex_lock(&import->proxiesMutex);
- if (import->proxies != NULL) {
- hash_map_iterator_pt iter = hashMapIterator_create(import->proxies);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- struct service_proxy *proxy = hashMapEntry_getValue(entry);
- importRegistration_destroyProxy(proxy);
- }
- hashMapIterator_destroy(iter);
- }
- pthread_mutex_unlock(&import->proxiesMutex);
- }
-}
-
-void importRegistration_destroy(import_registration_pt import) {
- if (import != NULL) {
- if (import->proxies != NULL) {
- hashMap_destroy(import->proxies, false, false);
- import->proxies = NULL;
- }
-
- pthread_mutex_destroy(&import->mutex);
- pthread_mutex_destroy(&import->proxiesMutex);
-
- if (import->factory != NULL) {
- free(import->factory);
- }
-
- if(import->version!=NULL){
- version_destroy(import->version);
- }
- free(import);
- }
-}
-
-celix_status_t importRegistration_start(import_registration_pt import) {
- celix_status_t status = CELIX_SUCCESS;
- if (import->factoryReg == NULL && import->factory != NULL) {
- properties_pt props = NULL;
- properties_copy(import->endpoint->properties, &props);
- status = bundleContext_registerServiceFactory(import->context, (char *)import->classObject, import->factory, props, &import->factoryReg);
- } else {
- status = CELIX_ILLEGAL_STATE;
- }
- return status;
-}
-
-celix_status_t importRegistration_stop(import_registration_pt import) {
- celix_status_t status = CELIX_SUCCESS;
-
- if (import->factoryReg != NULL) {
- serviceRegistration_unregister(import->factoryReg);
- import->factoryReg = NULL;
- }
-
- importRegistration_clearProxies(import);
-
- return status;
-}
-
-
-celix_status_t importRegistration_getService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
- celix_status_t status = CELIX_SUCCESS;
-
- /*
- module_pt module = NULL;
- char *name = NULL;
- bundle_getCurrentModule(bundle, &module);
- module_getSymbolicName(module, &name);
- printf("getting service for bundle '%s'\n", name);
- */
-
-
- pthread_mutex_lock(&import->proxiesMutex);
- struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
- if (proxy == NULL) {
- status = importRegistration_createProxy(import, bundle, &proxy);
- if (status == CELIX_SUCCESS) {
- hashMap_put(import->proxies, bundle, proxy);
- }
- }
-
- if (status == CELIX_SUCCESS) {
- proxy->count += 1;
- *out = proxy->service;
- }
- pthread_mutex_unlock(&import->proxiesMutex);
-
- return status;
-}
-
-static celix_status_t importRegistration_createProxy(import_registration_pt import, bundle_pt bundle, struct service_proxy **out) {
- celix_status_t status;
- dyn_interface_type* intf = NULL;
- FILE *descriptor = NULL;
-
- status = dfi_findDescriptor(import->context, bundle, import->classObject, &descriptor);
-
- if (status != CELIX_SUCCESS || descriptor == NULL) {
- //TODO use log helper logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", import->classObject);
- fprintf(stderr, "RSA_DFI: Cannot find/open descriptor for '%s'", import->classObject);
- return CELIX_BUNDLE_EXCEPTION;
- }
-
- if (status == CELIX_SUCCESS) {
- int rc = dynInterface_parse(descriptor, &intf);
- fclose(descriptor);
- if (rc != 0 || intf==NULL) {
- return CELIX_BUNDLE_EXCEPTION;
- }
- }
-
- /* Check if the imported service version is compatible with the one in the consumer descriptor */
- version_pt consumerVersion = NULL;
- bool isCompatible = false;
- dynInterface_getVersion(intf,&consumerVersion);
- version_isCompatible(consumerVersion,import->version,&isCompatible);
-
- if(!isCompatible){
- char* cVerString = NULL;
- char* pVerString = NULL;
- version_toString(consumerVersion,&cVerString);
- version_toString(import->version,&pVerString);
- printf("Service version mismatch: consumer has %s, provider has %s. NOT creating proxy.\n",cVerString,pVerString);
- dynInterface_destroy(intf);
- free(cVerString);
- free(pVerString);
- status = CELIX_SERVICE_EXCEPTION;
- }
-
- struct service_proxy *proxy = NULL;
- if (status == CELIX_SUCCESS) {
- proxy = calloc(1, sizeof(*proxy));
- if (proxy == NULL) {
- status = CELIX_ENOMEM;
- }
- }
-
- if (status == CELIX_SUCCESS) {
- proxy->intf = intf;
- size_t count = dynInterface_nrOfMethods(proxy->intf);
- proxy->service = calloc(1 + count, sizeof(void *));
- if (proxy->service == NULL) {
- status = CELIX_ENOMEM;
- }
- }
-
- if (status == CELIX_SUCCESS) {
- void **serv = proxy->service;
- serv[0] = import;
-
- struct methods_head *list = NULL;
- dynInterface_methods(proxy->intf, &list);
- struct method_entry *entry = NULL;
- void (*fn)(void) = NULL;
- int index = 0;
- TAILQ_FOREACH(entry, list, entries) {
- int rc = dynFunction_createClosure(entry->dynFunc, importRegistration_proxyFunc, entry, &fn);
- serv[index + 1] = fn;
- index += 1;
-
- if (rc != 0) {
- status = CELIX_BUNDLE_EXCEPTION;
- break;
- }
- }
- }
-
- if (status == CELIX_SUCCESS) {
- *out = proxy;
- } else if (proxy != NULL) {
- if (proxy->intf != NULL) {
- dynInterface_destroy(proxy->intf);
- proxy->intf = NULL;
- }
- free(proxy->service);
- free(proxy);
- }
-
- return status;
-}
-
-static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal) {
- int status = CELIX_SUCCESS;
- struct method_entry *entry = userData;
- import_registration_pt import = *((void **)args[0]);
-
- if (import == NULL || import->send == NULL) {
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
-
- char *invokeRequest = NULL;
- if (status == CELIX_SUCCESS) {
- status = jsonRpc_prepareInvokeRequest(entry->dynFunc, entry->id, args, &invokeRequest);
- //printf("Need to send following json '%s'\n", invokeRequest);
- }
-
-
- if (status == CELIX_SUCCESS) {
- char *reply = NULL;
- int rc = 0;
- //printf("sending request\n");
- celixThreadMutex_lock(&import->mutex);
- if (import->send != NULL) {
- import->send(import->sendHandle, import->endpoint, invokeRequest, &reply, &rc);
- }
- celixThreadMutex_unlock(&import->mutex);
- //printf("request sended. got reply '%s' with status %i\n", reply, rc);
-
- if (rc == 0) {
- //fjprintf("Handling reply '%s'\n", reply);
- status = jsonRpc_handleReply(entry->dynFunc, reply, args);
- }
-
- *(int *) returnVal = rc;
-
- free(invokeRequest); //Allocated by json_dumps in jsonRpc_prepareInvokeRequest
- free(reply); //Allocated by json_dumps in remoteServiceAdmin_send through curl call
- }
-
- if (status != CELIX_SUCCESS) {
- //TODO log error
- }
-}
-
-celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) {
- celix_status_t status = CELIX_SUCCESS;
-
- assert(import != NULL);
- assert(import->proxies != NULL);
-
- pthread_mutex_lock(&import->proxiesMutex);
-
- struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
- if (proxy != NULL) {
- if (*out == proxy->service) {
- proxy->count -= 1;
- } else {
- status = CELIX_ILLEGAL_ARGUMENT;
- }
-
- if (proxy->count == 0) {
- hashMap_remove(import->proxies, bundle);
- importRegistration_destroyProxy(proxy);
- }
- }
-
- pthread_mutex_unlock(&import->proxiesMutex);
-
- return status;
-}
-
-static void importRegistration_destroyProxy(struct service_proxy *proxy) {
- if (proxy != NULL) {
- if (proxy->intf != NULL) {
- dynInterface_destroy(proxy->intf);
- }
- if (proxy->service != NULL) {
- free(proxy->service);
- }
- free(proxy);
- }
-}
-
-
-celix_status_t importRegistration_close(import_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
- importRegistration_stop(registration);
- return status;
-}
-
-celix_status_t importRegistration_getException(import_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
- //TODO
- return status;
-}
-
-celix_status_t importRegistration_getImportReference(import_registration_pt registration, import_reference_pt *reference) {
- celix_status_t status = CELIX_SUCCESS;
- //TODO
- return status;
-}
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
-
-celix_status_t importReference_getImportedService(import_reference_pt reference) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h b/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h
deleted file mode 100644
index aac4bc7..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/src/import_registration_dfi.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#ifndef CELIX_IMPORT_REGISTRATION_DFI_H
-#define CELIX_IMPORT_REGISTRATION_DFI_H
-
-#include "import_registration.h"
-#include "dfi_utils.h"
-
-#include <celix_errno.h>
-
-typedef void (*send_func_type)(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
-
-celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt description, const char *classObject, const char* serviceVersion,
- import_registration_pt *import);
-celix_status_t importRegistration_close(import_registration_pt import);
-void importRegistration_destroy(import_registration_pt import);
-
-celix_status_t importRegistration_setSendFn(import_registration_pt reg,
- send_func_type,
- void *handle);
-celix_status_t importRegistration_start(import_registration_pt import);
-celix_status_t importRegistration_stop(import_registration_pt import);
-
-celix_status_t importRegistration_getService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **service);
-celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **service);
-
-#endif //CELIX_IMPORT_REGISTRATION_DFI_H
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c
deleted file mode 100644
index d4cc765..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_activator.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_activator.c
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdlib.h>
-#include <remote_service_admin.h>
-
-#include "remote_service_admin_dfi.h"
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-
-#include "export_registration_dfi.h"
-#include "import_registration_dfi.h"
-
-struct activator {
- remote_service_admin_pt admin;
- remote_service_admin_service_pt adminService;
- service_registration_pt registration;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator;
-
- activator = calloc(1, sizeof(*activator));
- if (!activator) {
- status = CELIX_ENOMEM;
- } else {
- activator->admin = NULL;
- activator->registration = NULL;
-
- *userData = activator;
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
- remote_service_admin_service_pt remoteServiceAdmin = NULL;
-
- status = remoteServiceAdmin_create(context, &activator->admin);
- if (status == CELIX_SUCCESS) {
- remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
- if (!remoteServiceAdmin) {
- status = CELIX_ENOMEM;
- } else {
- remoteServiceAdmin->admin = activator->admin;
- remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
-
- remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
- remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
- remoteServiceAdmin->importService = remoteServiceAdmin_importService;
-
- remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
- remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
-
- remoteServiceAdmin->exportRegistration_close = remoteServiceAdmin_removeExportedService;
- remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
- remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
-
- remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
- remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
-
- remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
- remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
- remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
-
- status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
- activator->adminService = remoteServiceAdmin;
- }
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- serviceRegistration_unregister(activator->registration);
- activator->registration = NULL;
-
- remoteServiceAdmin_stop(activator->admin);
- remoteServiceAdmin_destroy(&activator->admin);
-
- free(activator->adminService);
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- free(activator);
-
- return status;
-}
-
-
[2/8] celix git commit: CELIX-417: Refactors CMake usage for the RSA
bundles
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c
deleted file mode 100644
index 9feab9f..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_impl.c
- *
- * \date May 21, 2015
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <ifaddrs.h>
-#include <string.h>
-#include <uuid/uuid.h>
-#include <curl/curl.h>
-
-#include <jansson.h>
-#include "json_serializer.h"
-#include "remote_service_admin.h"
-#include "celix_threads.h"
-#include "hash_map.h"
-#include "array_list.h"
-
-#include "import_registration_dfi.h"
-#include "export_registration_dfi.h"
-#include "remote_service_admin_dfi.h"
-#include "dyn_interface.h"
-#include "json_rpc.h"
-
-#include "remote_constants.h"
-#include "constants.h"
-#include "civetweb.h"
-
-// defines how often the webserver is restarted (with an increased port number)
-#define MAX_NUMBER_OF_RESTARTS 5
-
-
-#define RSA_LOG_ERROR(admin, msg, ...) \
- logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
-
-#define RSA_LOG_WARNING(admin, msg, ...) \
- logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
-
-#define RSA_LOG_DEBUG(admin, msg, ...) \
- logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
-
-struct remote_service_admin {
- bundle_context_pt context;
- log_helper_pt loghelper;
-
- celix_thread_mutex_t exportedServicesLock;
- hash_map_pt exportedServices;
-
- celix_thread_mutex_t importedServicesLock;
- array_list_pt importedServices;
-
- char *port;
- char *ip;
-
- struct mg_context *ctx;
-};
-
-struct post {
- const char *readptr;
- int size;
-};
-
-struct get {
- char *writeptr;
- int size;
-};
-
-#define OSGI_RSA_REMOTE_PROXY_FACTORY "remote_proxy_factory"
-#define OSGI_RSA_REMOTE_PROXY_TIMEOUT "remote_proxy_timeout"
-
-static const char *data_response_headers =
- "HTTP/1.1 200 OK\r\n"
- "Cache: no-cache\r\n"
- "Content-Type: application/json\r\n"
- "\r\n";
-
-static const char *no_content_response_headers =
- "HTTP/1.1 204 OK\r\n";
-
-// TODO do we need to specify a non-Amdatu specific configuration type?!
-static const char * const CONFIGURATION_TYPE = "org.amdatu.remote.admin.http";
-static const char * const ENDPOINT_URL = "org.amdatu.remote.admin.http.url";
-
-static const char *DEFAULT_PORT = "8888";
-static const char *DEFAULT_IP = "127.0.0.1";
-
-static const unsigned int DEFAULT_TIMEOUT = 0;
-
-static int remoteServiceAdmin_callback(struct mg_connection *conn);
-static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, char *interface, endpoint_description_pt *description);
-static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus);
-static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip);
-static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp);
-static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp);
-static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...);
-
-celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin) {
- celix_status_t status = CELIX_SUCCESS;
-
- *admin = calloc(1, sizeof(**admin));
-
- if (!*admin) {
- status = CELIX_ENOMEM;
- } else {
- unsigned int port_counter = 0;
- const char *port = NULL;
- const char *ip = NULL;
- char *detectedIp = NULL;
- (*admin)->context = context;
- (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
- arrayList_create(&(*admin)->importedServices);
-
- celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
- celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
-
- if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
- logHelper_start((*admin)->loghelper);
- dynCommon_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- dynType_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- dynFunction_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- dynInterface_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- jsonSerializer_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- jsonRpc_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
- }
-
- bundleContext_getProperty(context, "RSA_PORT", &port);
- if (port == NULL) {
- port = (char *)DEFAULT_PORT;
- }
-
- bundleContext_getProperty(context, "RSA_IP", &ip);
- if (ip == NULL) {
- const char *interface = NULL;
-
- bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
- if ((interface != NULL) && (remoteServiceAdmin_getIpAdress((char*)interface, &detectedIp) != CELIX_SUCCESS)) {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: Could not retrieve IP adress for interface %s", interface);
- }
-
- if (ip == NULL) {
- remoteServiceAdmin_getIpAdress(NULL, &detectedIp);
- }
-
- ip = detectedIp;
- }
-
- if (ip != NULL) {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Using %s for service annunciation", ip);
- (*admin)->ip = strdup(ip);
- }
- else {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No IP address for service annunciation set. Using %s", DEFAULT_IP);
- (*admin)->ip = strdup((char*) DEFAULT_IP);
- }
-
- if (detectedIp != NULL) {
- free(detectedIp);
- }
-
- // Prepare callbacks structure. We have only one callback, the rest are NULL.
- struct mg_callbacks callbacks;
- memset(&callbacks, 0, sizeof(callbacks));
- callbacks.begin_request = remoteServiceAdmin_callback;
-
- char newPort[10];
-
- do {
-
- const char *options[] = { "listening_ports", port, "num_threads", "5", NULL};
-
- (*admin)->ctx = mg_start(&callbacks, (*admin), options);
-
- if ((*admin)->ctx != NULL) {
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Start webserver: %s", port);
- (*admin)->port = strdup(port);
-
- }
- else {
- errno = 0;
- char* endptr = (char*)port;
- int currentPort = strtol(port, &endptr, 10);
-
- if (*endptr || errno != 0) {
- currentPort = strtol(DEFAULT_PORT, NULL, 10);
- }
-
- port_counter++;
- snprintf(&newPort[0], 6, "%d", (currentPort+1));
-
- logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting rsa server on port %s - retrying on port %s...", port, newPort);
- port = newPort;
- }
- } while(((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS));
-
- }
-
- return status;
-}
-
-
-celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin)
-{
- celix_status_t status = CELIX_SUCCESS;
-
- free((*admin)->ip);
- free((*admin)->port);
- free(*admin);
-
- //TODO destroy exports/imports
-
- *admin = NULL;
-
- return status;
-}
-
-
-celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin) {
- celix_status_t status = CELIX_SUCCESS;
-
- celixThreadMutex_lock(&admin->exportedServicesLock);
-
- hash_map_iterator_pt iter = hashMapIterator_create(admin->exportedServices);
- while (hashMapIterator_hasNext(iter)) {
- array_list_pt exports = hashMapIterator_nextValue(iter);
- int i;
- for (i = 0; i < arrayList_size(exports); i++) {
- export_registration_pt export = arrayList_get(exports, i);
- if (export != NULL) {
- exportRegistration_stop(export);
- exportRegistration_destroy(export);
- }
- }
- arrayList_destroy(exports);
- }
- hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&admin->exportedServicesLock);
-
- celixThreadMutex_lock(&admin->importedServicesLock);
- int i;
- int size = arrayList_size(admin->importedServices);
- for (i = 0; i < size ; i += 1) {
- import_registration_pt import = arrayList_get(admin->importedServices, i);
- if (import != NULL) {
- importRegistration_stop(import);
- importRegistration_destroy(import);
- }
- }
- celixThreadMutex_unlock(&admin->importedServicesLock);
-
- if (admin->ctx != NULL) {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Stopping webserver...");
- mg_stop(admin->ctx);
- admin->ctx = NULL;
- }
-
- hashMap_destroy(admin->exportedServices, false, false);
- arrayList_destroy(admin->importedServices);
-
- logHelper_stop(admin->loghelper);
- logHelper_destroy(&admin->loghelper);
-
- return status;
-}
-
-/**
- * Request: http://host:port/services/{service}/{request}
- */
-//void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) {
-
-celix_status_t importRegistration_getFactory(import_registration_pt import, service_factory_pt *factory);
-
-static int remoteServiceAdmin_callback(struct mg_connection *conn) {
- int result = 1; // zero means: let civetweb handle it further, any non-zero value means it is handled by us...
-
- const struct mg_request_info *request_info = mg_get_request_info(conn);
- if (request_info->uri != NULL) {
- remote_service_admin_pt rsa = request_info->user_data;
-
-
- if (strncmp(request_info->uri, "/service/", 9) == 0 && strcmp("POST", request_info->request_method) == 0) {
-
- // uri = /services/myservice/call
- const char *uri = request_info->uri;
- // rest = myservice/call
-
- const char *rest = uri+9;
- char *interfaceStart = strchr(rest, '/');
- int pos = interfaceStart - rest;
- char service[pos+1];
- strncpy(service, rest, pos);
- service[pos] = '\0';
- unsigned long serviceId = strtoul(service,NULL,10);
-
- celixThreadMutex_lock(&rsa->exportedServicesLock);
-
- //find endpoint
- export_registration_pt export = NULL;
- hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
- while (hashMapIterator_hasNext(iter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
- array_list_pt exports = hashMapEntry_getValue(entry);
- int expIt = 0;
- for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
- export_registration_pt check = arrayList_get(exports, expIt);
- export_reference_pt ref = NULL;
- exportRegistration_getExportReference(check, &ref);
- endpoint_description_pt checkEndpoint = NULL;
- exportReference_getExportedEndpoint(ref, &checkEndpoint);
- if (serviceId == checkEndpoint->serviceId) {
- export = check;
- free(ref);
- break;
- }
- free(ref);
- }
- }
- hashMapIterator_destroy(iter);
-
- if (export != NULL) {
-
- uint64_t datalength = request_info->content_length;
- char* data = malloc(datalength + 1);
- mg_read(conn, data, datalength);
- data[datalength] = '\0';
-
- char *response = NULL;
- int responceLength = 0;
- int rc = exportRegistration_call(export, data, -1, &response, &responceLength);
- if (rc != CELIX_SUCCESS) {
- RSA_LOG_ERROR(rsa, "Error trying to invoke remove service, got error %i\n", rc);
- }
-
- if (rc == CELIX_SUCCESS && response != NULL) {
- mg_write(conn, data_response_headers, strlen(data_response_headers));
- mg_write(conn, response, strlen(response));
- free(response);
- } else {
- mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
- }
- result = 1;
-
- free(data);
- } else {
- result = 0;
- RSA_LOG_WARNING(rsa, "NO export registration found for service id %lu", serviceId);
- }
-
- celixThreadMutex_unlock(&rsa->exportedServicesLock);
-
- }
- }
-
- return result;
-}
-
-celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations) {
- celix_status_t status;
-
- arrayList_create(registrations);
- array_list_pt references = NULL;
- service_reference_pt reference = NULL;
- char filter [256];
-
- snprintf(filter, 256, "(%s=%s)", (char *)OSGI_FRAMEWORK_SERVICE_ID, serviceId);
-
- status = bundleContext_getServiceReferences(admin->context, NULL, filter, &references);
-
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: exportService called for serviceId %s", serviceId);
-
- int i;
- int size = arrayList_size(references);
- for (i = 0; i < size; i += 1) {
- if (i == 0) {
- reference = arrayList_get(references, i);
- } else {
- bundleContext_ungetServiceReference(admin->context, arrayList_get(references, i));
- }
- }
- arrayList_destroy(references);
-
- if (reference == NULL) {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);
- status = CELIX_ILLEGAL_STATE;
- }
-
- const char *exports = NULL;
- const char *provided = NULL;
- if (status == CELIX_SUCCESS) {
- serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
- serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_OBJECTCLASS, &provided);
-
- if (exports == NULL || provided == NULL || strcmp(exports, provided) != 0) {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No Services to export.");
- status = CELIX_ILLEGAL_STATE;
- } else {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
- }
- }
-
- if (status == CELIX_SUCCESS) {
- const char *interface = provided;
- endpoint_description_pt endpoint = NULL;
- export_registration_pt registration = NULL;
-
- remoteServiceAdmin_createEndpointDescription(admin, reference, properties, (char*)interface, &endpoint);
- //TODO precheck if descriptor exists
- status = exportRegistration_create(admin->loghelper, reference, endpoint, admin->context, ®istration);
- if (status == CELIX_SUCCESS) {
- status = exportRegistration_start(registration);
- if (status == CELIX_SUCCESS) {
- arrayList_add(*registrations, registration);
- }
- }
- }
-
-
- if (status == CELIX_SUCCESS) {
- celixThreadMutex_lock(&admin->exportedServicesLock);
- hashMap_put(admin->exportedServices, reference, *registrations);
- celixThreadMutex_unlock(&admin->exportedServicesLock);
- }
- else{
- arrayList_destroy(*registrations);
- *registrations = NULL;
- }
-
- return status;
-}
-
-celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration) {
- celix_status_t status;
-
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing exported service");
-
- export_reference_pt ref = NULL;
- status = exportRegistration_getExportReference(registration, &ref);
-
- if (status == CELIX_SUCCESS && ref != NULL) {
- service_reference_pt servRef;
- celixThreadMutex_lock(&admin->exportedServicesLock);
- exportReference_getExportedService(ref, &servRef);
-
- array_list_pt exports = (array_list_pt)hashMap_remove(admin->exportedServices, servRef);
- if(exports!=NULL){
- arrayList_destroy(exports);
- }
-
- exportRegistration_close(registration);
- exportRegistration_destroy(registration);
-
- celixThreadMutex_unlock(&admin->exportedServicesLock);
-
- free(ref);
-
- } else {
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot find reference for registration");
- }
-
- return status;
-}
-
-static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, char *interface, endpoint_description_pt *endpoint) {
-
- celix_status_t status = CELIX_SUCCESS;
- properties_pt endpointProperties = properties_create();
-
-
- unsigned int size = 0;
- char **keys;
-
- serviceReference_getPropertyKeys(reference, &keys, &size);
- for (int i = 0; i < size; i++) {
- char *key = keys[i];
- const char *value = NULL;
-
- if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS
- && strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
- && strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
- properties_set(endpointProperties, key, value);
- }
- }
-
- hash_map_entry_pt entry = hashMap_getEntry(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
-
- char* key = hashMapEntry_getKey(entry);
- char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
- const char *uuid = NULL;
-
- char buf[512];
- snprintf(buf, 512, "/service/%s/%s", serviceId, interface);
-
- char url[1024];
- snprintf(url, 1024, "http://%s:%s%s", admin->ip, admin->port, buf);
-
- uuid_t endpoint_uid;
- uuid_generate(endpoint_uid);
- char endpoint_uuid[37];
- uuid_unparse_lower(endpoint_uid, endpoint_uuid);
-
- bundleContext_getProperty(admin->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
- properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
- properties_set(endpointProperties, (char*) OSGI_FRAMEWORK_OBJECTCLASS, interface);
- properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId);
- properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, endpoint_uuid);
- properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED, "true");
- properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) CONFIGURATION_TYPE);
- properties_set(endpointProperties, (char*) ENDPOINT_URL, url);
-
- if (props != NULL) {
- hash_map_iterator_pt propIter = hashMapIterator_create(props);
- while (hashMapIterator_hasNext(propIter)) {
- hash_map_entry_pt entry = hashMapIterator_nextEntry(propIter);
- properties_set(endpointProperties, (char*)hashMapEntry_getKey(entry), (char*)hashMapEntry_getValue(entry));
- }
- hashMapIterator_destroy(propIter);
- }
-
- *endpoint = calloc(1, sizeof(**endpoint));
- if (!*endpoint) {
- status = CELIX_ENOMEM;
- } else {
- (*endpoint)->id = (char*)properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
- const char *serviceId = NULL;
- serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
- (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
- (*endpoint)->frameworkUUID = (char*) properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
- (*endpoint)->service = strndup(interface, 1024*10);
- (*endpoint)->properties = endpointProperties;
- }
-
- free(key);
- free(serviceId);
- free(keys);
-
- return status;
-}
-
-static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip) {
- celix_status_t status = CELIX_BUNDLE_EXCEPTION;
-
- struct ifaddrs *ifaddr, *ifa;
- char host[NI_MAXHOST];
-
- if (getifaddrs(&ifaddr) != -1)
- {
- for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
- {
- if (ifa->ifa_addr == NULL)
- continue;
-
- if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
- if (interface == NULL) {
- *ip = strdup(host);
- status = CELIX_SUCCESS;
- }
- else if (strcmp(ifa->ifa_name, interface) == 0) {
- *ip = strdup(host);
- status = CELIX_SUCCESS;
- }
- }
- }
-
- freeifaddrs(ifaddr);
- }
-
- return status;
-}
-
-
-celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description)
-{
- celix_status_t status = CELIX_SUCCESS;
-
- properties_destroy((*description)->properties);
- free((*description)->service);
- free(*description);
-
- return status;
-}
-
-
-celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
-
-celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services) {
- celix_status_t status = CELIX_SUCCESS;
- return status;
-}
-
-celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpointDescription, import_registration_pt *out) {
- celix_status_t status = CELIX_SUCCESS;
- import_registration_pt import = NULL;
-
- const char *objectClass = properties_get(endpointDescription->properties, "objectClass");
- const char *serviceVersion = properties_get(endpointDescription->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION);
-
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "Registering service factory (proxy) for service '%s'\n", objectClass);
-
- if (objectClass != NULL) {
- status = importRegistration_create(admin->context, endpointDescription, objectClass, serviceVersion, &import);
- }
- if (status == CELIX_SUCCESS && import != NULL) {
- importRegistration_setSendFn(import, (send_func_type) remoteServiceAdmin_send, admin);
- }
-
- if (status == CELIX_SUCCESS && import != NULL) {
- status = importRegistration_start(import);
- }
-
- celixThreadMutex_lock(&admin->importedServicesLock);
- arrayList_add(admin->importedServices, import);
- celixThreadMutex_unlock(&admin->importedServicesLock);
-
- if (status == CELIX_SUCCESS) {
- *out = import;
- }
-
- return status;
-}
-
-
-celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration) {
- celix_status_t status = CELIX_SUCCESS;
- logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing imported service");
-
- celixThreadMutex_lock(&admin->importedServicesLock);
- int i;
- int size = arrayList_size(admin->importedServices);
- import_registration_pt current = NULL;
- for (i = 0; i < size; i += 1) {
- current = arrayList_get(admin->importedServices, i);
- if (current == registration) {
- arrayList_remove(admin->importedServices, i);
- importRegistration_close(current);
- importRegistration_destroy(current);
- break;
- }
- }
- celixThreadMutex_unlock(&admin->importedServicesLock);
-
- return status;
-}
-
-
-static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
- remote_service_admin_pt rsa = handle;
- struct post post;
- post.readptr = request;
- post.size = strlen(request);
-
- struct get get;
- get.size = 0;
- get.writeptr = malloc(1);
-
- char *serviceUrl = (char*)properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
- char url[256];
- snprintf(url, 256, "%s", serviceUrl);
-
- // assume the default timeout
- int timeout = DEFAULT_TIMEOUT;
-
- const char *timeoutStr = NULL;
- // Check if the endpoint has a timeout, if so, use it.
- timeoutStr = (char*) properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
- if (timeoutStr == NULL) {
- // If not, get the global variable and use that one.
- bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
- }
-
- // Update timeout if a property is used to set it.
- if (timeoutStr != NULL) {
- timeout = atoi(timeoutStr);
- }
-
- celix_status_t status = CELIX_SUCCESS;
- CURL *curl;
- CURLcode res;
-
- curl = curl_easy_init();
- if(!curl) {
- status = CELIX_ILLEGAL_STATE;
- } else {
- curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_POST, 1L);
- curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
- curl_easy_setopt(curl, CURLOPT_READDATA, &post);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
- logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: Performing curl post\n");
- res = curl_easy_perform(curl);
-
- *reply = get.writeptr;
- *replyStatus = res;
-
- curl_easy_cleanup(curl);
- }
-
- return status;
-}
-
-static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp) {
- struct post *post = userp;
-
- if (post->size) {
- *(char *) ptr = post->readptr[0];
- post->readptr++;
- post->size--;
- return 1;
- }
-
- return 0;
-}
-
-static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp) {
- size_t realsize = size * nmemb;
- struct get *mem = (struct get *)userp;
-
- mem->writeptr = realloc(mem->writeptr, mem->size + realsize + 1);
- if (mem->writeptr == NULL) {
- /* out of memory! */
- printf("not enough memory (realloc returned NULL)");
- exit(EXIT_FAILURE);
- }
-
- memcpy(&(mem->writeptr[mem->size]), contents, realsize);
- mem->size += realsize;
- mem->writeptr[mem->size] = 0;
-
- return realsize;
-}
-
-
-static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...) {
- va_list ap;
- va_start(ap, msg);
- int levels[5] = {0, OSGI_LOGSERVICE_ERROR, OSGI_LOGSERVICE_WARNING, OSGI_LOGSERVICE_INFO, OSGI_LOGSERVICE_DEBUG};
-
- char buf1[256];
- snprintf(buf1, 256, "FILE:%s, LINE:%i, MSG:", file, line);
-
- char buf2[256];
- vsnprintf(buf2, 256, msg, ap);
- logHelper_log(admin->loghelper, levels[level], "%s%s", buf1, buf2);
- va_end(ap);
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h b/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h
deleted file mode 100644
index 8b282f1..0000000
--- a/remote_services/remote_service_admin_dfi/rsa/src/remote_service_admin_dfi.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_http_impl.h
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
-#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
-
-
-#include "bundle_context.h"
-#include "endpoint_description.h"
-
-//typedef struct remote_service_admin *remote_service_admin_pt;
-
-celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
-celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
-
-celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
-
-celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
-celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration);
-celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services);
-celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services);
-celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
-celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
-
-
-celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
-celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service);
-
-celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
-celix_status_t importReference_getImportedService(import_reference_pt reference);
-
-celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
-
-#endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
deleted file mode 100644
index b3b272e..0000000
--- a/remote_services/remote_service_admin_dfi/rsa_tst/CMakeLists.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-include_directories(
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include
- ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_service/public/include
- bundle
-)
-
-add_subdirectory(bundle)
-
-SET(CMAKE_SKIP_BUILD_RPATH FALSE) #TODO needed?
-SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #TODO needed?
-SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework" "${PROJECT_BINARY_DIR}/utils" "${PROJECT_BINARY_DIR}/dfi")
-
-add_executable(test_rsa_dfi
- run_tests.cpp
- rsa_tests.cpp
- rsa_client_server_tests.cpp
-)
-target_link_libraries(test_rsa_dfi PRIVATE Celix::framework ${CURL_LIBRARIES} ${CPPUTEST_LIBRARY} remote_service_admin_common)
-
-get_property(rsa_bundle_file TARGET remote_service_admin_dfi PROPERTY BUNDLE_FILE)
-get_property(calc_bundle_file TARGET calculator PROPERTY BUNDLE_FILE)
-get_property(calculator_shell_bundle_file TARGET calculator_shell PROPERTY BUNDLE_FILE)
-get_property(discovery_configured_bundle_file TARGET discovery_configured PROPERTY BUNDLE_FILE)
-get_property(topology_manager_bundle_file TARGET topology_manager PROPERTY BUNDLE_FILE)
-get_property(tst_bundle_file TARGET rsa_dfi_tst_bundle PROPERTY BUNDLE_FILE)
-
-configure_file(config.properties.in config.properties)
-configure_file(client.properties.in client.properties)
-configure_file(server.properties.in server.properties)
-
-add_dependencies(test_rsa_dfi remote_service_admin_dfi calculator)
-
-add_test(NAME run_test_rsa_dfi COMMAND test_rsa_dfi)
-SETUP_TARGET_FOR_COVERAGE(test_rsa_dfi_cov test_rsa_dfi ${CMAKE_BINARY_DIR}/coverage/test_rsa_dfi/test_rsa_dfi)
-
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt b/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
deleted file mode 100644
index 65b18e8..0000000
--- a/remote_services/remote_service_admin_dfi/rsa_tst/bundle/CMakeLists.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-add_bundle(rsa_dfi_tst_bundle
- VERSION 0.0.1
- SOURCES
- tst_activator.c
-)
-
-bundle_files(rsa_dfi_tst_bundle
- ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator2.descriptor
- DESTINATION .
-)
-target_include_directories(rsa_dfi_tst_bundle PRIVATE calculator)
-target_link_libraries(rsa_dfi_tst_bundle PRIVATE ${CPPUTEST_LIBRARY} calculator_api)
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa_tst/bundle/tst_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/bundle/tst_activator.c b/remote_services/remote_service_admin_dfi/rsa_tst/bundle/tst_activator.c
deleted file mode 100644
index f5838f8..0000000
--- a/remote_services/remote_service_admin_dfi/rsa_tst/bundle/tst_activator.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <service_tracker_customizer.h>
-#include <service_tracker.h>
-
-#include "bundle_activator.h"
-#include "bundle_context.h"
-#include "service_registration.h"
-#include "service_reference.h"
-#include "celix_errno.h"
-
-#include "tst_service.h"
-#include "calculator_service.h"
-
-
-struct activator {
- bundle_context_pt context;
- struct tst_service serv;
- service_registration_pt reg;
-
- service_tracker_customizer_pt cust;
- service_tracker_pt tracker;
- calculator_service_pt calc;
-};
-
-static celix_status_t addCalc(void * handle, service_reference_pt reference, void * service);
-static celix_status_t removeCalc(void * handle, service_reference_pt reference, void * service);
-static int test(void *handle);
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **out) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *act = calloc(1, sizeof(*act));
- if (act != NULL) {
- act->context = context;
- act->serv.handle = act;
- act->serv.test = test;
-
- status = serviceTrackerCustomizer_create(act, NULL, addCalc, NULL, removeCalc, &act->cust);
- status = CELIX_DO_IF(status, serviceTracker_create(context, CALCULATOR2_SERVICE, act->cust, &act->tracker));
-
- } else {
- status = CELIX_ENOMEM;
- }
-
- if (status == CELIX_SUCCESS) {
- *out = act;
- } else if (act != NULL) {
- if (act->cust != NULL) {
- free(act->cust);
- act->cust = NULL;
- }
- if (act->tracker != NULL) {
- serviceTracker_destroy(act->tracker);
- act->tracker = NULL;
- }
- free(act);
- }
-
- return CELIX_SUCCESS;
-}
-
-static celix_status_t addCalc(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator * act = handle;
- act->calc = service;
- return status;
-}
-
-static celix_status_t removeCalc(void * handle, service_reference_pt reference, void * service) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator * act = handle;
- if (act->calc == service) {
- act->calc = NULL;
- }
- return status;
-
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator * act = userData;
-
- act->reg = NULL;
- status = bundleContext_registerService(context, (char *)TST_SERVICE_NAME, &act->serv, NULL, &act->reg);
-
- status = CELIX_DO_IF(status, serviceTracker_open(act->tracker));
-
-
- return status;
-}
-
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator * act = userData;
-
- status = serviceRegistration_unregister(act->reg);
- status = CELIX_DO_IF(status, serviceTracker_close(act->tracker));
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- struct activator *act = userData;
- if (act != NULL) {
- if (act->tracker != NULL) {
- serviceTracker_destroy(act->tracker);
- act->tracker = NULL;
- }
- free(act);
- }
- return CELIX_SUCCESS;
-}
-
-static int test(void *handle) {
- int status = 0;
- struct activator *act = handle;
-
- double result = -1.0;
-
- int rc = 1;
- if (act->calc != NULL) {
- rc = act->calc->sqrt(act->calc->calculator, 4, &result);
- printf("calc result is %f\n", result);
- } else {
- printf("calc not ready\n");
- }
-
- if (rc != 0 || result != 2.0) {
- status = 1;
- }
- return status;
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa_tst/bundle/tst_service.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/bundle/tst_service.h b/remote_services/remote_service_admin_dfi/rsa_tst/bundle/tst_service.h
deleted file mode 100644
index c8ca2e7..0000000
--- a/remote_services/remote_service_admin_dfi/rsa_tst/bundle/tst_service.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#ifndef CELIX_TST_SERVICE_H
-#define CELIX_TST_SERVICE_H
-
-#define TST_SERVICE_NAME "tst_service"
-
-struct tst_service {
- void *handle;
- int (*test)(void *handle);
-};
-
-typedef struct tst_service *tst_service_pt;
-
-#endif //CELIX_TST_SERVICE_H
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa_tst/client.properties.in
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/client.properties.in b/remote_services/remote_service_admin_dfi/rsa_tst/client.properties.in
deleted file mode 100644
index a9a06fb..0000000
--- a/remote_services/remote_service_admin_dfi/rsa_tst/client.properties.in
+++ /dev/null
@@ -1,8 +0,0 @@
-cosgi.auto.start.1=@rsa_bundle_file@ @calculator_shell_bundle_file@ @discovery_configured_bundle_file@ @topology_manager_bundle_file@ @tst_bundle_file@
-LOGHELPER_ENABLE_STDOUT_FALLBACK=true
-RSA_PORT=50881
-DISCOVERY_CFG_SERVER_PORT=50991
-DISCOVERY_CFG_POLL_ENDPOINTS=http://127.0.0.1:50992/org.apache.celix.discovery.configured
-org.osgi.framework.storage.clean=onFirstInit
-org.osgi.framework.storage=.cacheClient
-DISCOVERY_CFG_POLL_INTERVAL=1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa_tst/config.properties.in
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/config.properties.in b/remote_services/remote_service_admin_dfi/rsa_tst/config.properties.in
deleted file mode 100644
index 5776ad8..0000000
--- a/remote_services/remote_service_admin_dfi/rsa_tst/config.properties.in
+++ /dev/null
@@ -1,20 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-cosgi.auto.start.1=@rsa_bundle_file@ @calc_bundle_file@
-LOGHELPER_ENABLE_STDOUT_FALLBACK=true
-org.osgi.framework.storage.clean=onFirstInit
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa_tst/rsa_client_server_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/rsa_client_server_tests.cpp b/remote_services/remote_service_admin_dfi/rsa_tst/rsa_client_server_tests.cpp
deleted file mode 100644
index d091746..0000000
--- a/remote_services/remote_service_admin_dfi/rsa_tst/rsa_client_server_tests.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <CppUTest/TestHarness.h>
-#include <remote_constants.h>
-#include <constants.h>
-#include <tst_service.h>
-#include "CppUTest/CommandLineTestRunner.h"
-#include "../../examples/calculator_service/public/include/calculator_service.h"
-
-extern "C" {
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-
-#include "celix_launcher.h"
-#include "framework.h"
-#include "remote_service_admin.h"
-#include "calculator_service.h"
-
- static framework_pt serverFramework = NULL;
- static bundle_context_pt serverContext = NULL;
-
- static framework_pt clientFramework = NULL;
- static bundle_context_pt clientContext = NULL;
-
- static void setupFm(void) {
- int rc = 0;
- bundle_pt bundle = NULL;
-
- //server
- rc = celixLauncher_launch("server.properties", &serverFramework);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- bundle = NULL;
- rc = framework_getFrameworkBundle(serverFramework, &bundle);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundle_getContext(bundle, &serverContext);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
-
- //client
- rc = celixLauncher_launch("client.properties", &clientFramework);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- bundle = NULL;
- rc = framework_getFrameworkBundle(clientFramework, &bundle);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundle_getContext(bundle, &clientContext);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- }
-
- static void teardownFm(void) {
- celixLauncher_stop(serverFramework);
- celixLauncher_waitForShutdown(serverFramework);
- celixLauncher_destroy(serverFramework);
-
- celixLauncher_stop(clientFramework);
- celixLauncher_waitForShutdown(clientFramework);
- celixLauncher_destroy(clientFramework);
-
- serverContext = NULL;
- serverFramework = NULL;
- clientContext = NULL;
- clientFramework = NULL;
- }
-
- static void test1(void) {
- celix_status_t rc;
- service_reference_pt ref = NULL;
- tst_service_pt tst = NULL;
- int retries = 4;
-
- while (ref == NULL && retries > 0) {
- printf("Waiting for service .. %d\n", retries);
- rc = bundleContext_getServiceReference(clientContext, (char *) TST_SERVICE_NAME, &ref);
- usleep(1000000);
- --retries;
- }
-
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(ref != NULL);
-
- rc = bundleContext_getService(clientContext, ref, (void **)&tst);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(tst != NULL);
-
- rc = tst->test(tst->handle);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- bool result;
- bundleContext_ungetService(clientContext, ref, &result);
- bundleContext_ungetServiceReference(clientContext, ref);
- }
-
-}
-
-
-TEST_GROUP(RsaDfiClientServerTests) {
- void setup() {
- setupFm();
- }
-
- void teardown() {
- teardownFm();
- }
-};
-
-TEST(RsaDfiClientServerTests, Test1) {
- test1();
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp b/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp
deleted file mode 100644
index 8b7988d..0000000
--- a/remote_services/remote_service_admin_dfi/rsa_tst/rsa_tests.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <CppUTest/TestHarness.h>
-#include <remote_constants.h>
-#include <constants.h>
-#include "CppUTest/CommandLineTestRunner.h"
-#include "../../examples/calculator_service/public/include/calculator_service.h"
-
-extern "C" {
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "celix_launcher.h"
-#include "framework.h"
-#include "remote_service_admin.h"
-#include "calculator_service.h"
-
-
- static framework_pt framework = NULL;
- static bundle_context_pt context = NULL;
-
- static service_reference_pt rsaRef = NULL;
- static remote_service_admin_service_pt rsa = NULL;
-
- static service_reference_pt calcRef = NULL;
- static calculator_service_pt calc = NULL;
-
- static void setupFm(void) {
- int rc = 0;
-
- rc = celixLauncher_launch("config.properties", &framework);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- bundle_pt bundle = NULL;
- rc = framework_getFrameworkBundle(framework, &bundle);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundle_getContext(bundle, &context);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundleContext_getServiceReference(context, (char *)OSGI_RSA_REMOTE_SERVICE_ADMIN, &rsaRef);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(rsaRef != NULL);
-
- rc = bundleContext_getService(context, rsaRef, (void **)&rsa);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundleContext_getServiceReference(context, (char *)CALCULATOR2_SERVICE, &calcRef);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(calcRef != NULL);
-
- rc = bundleContext_getService(context, calcRef, (void **)&calc);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- }
-
- static void teardownFm(void) {
- int rc = 0;
- rc = bundleContext_ungetService(context, rsaRef, NULL);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundleContext_ungetServiceReference(context, rsaRef);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundleContext_ungetService(context, calcRef, NULL);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundleContext_ungetServiceReference(context, calcRef);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- celixLauncher_stop(framework);
- celixLauncher_waitForShutdown(framework);
- celixLauncher_destroy(framework);
-
- rsaRef = NULL;
- rsa = NULL;
- calcRef = NULL;
- calc = NULL;
- context = NULL;
- framework = NULL;
- }
-
- static void testServices(void) {
- int rc = 0;
- array_list_pt exported = NULL;
- array_list_pt imported = NULL;
- arrayList_create(&exported);
- arrayList_create(&imported);
-
- rc = rsa->getExportedServices(rsa->admin, &exported);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK_EQUAL(0, arrayList_size(exported));
-
- rc = rsa->getImportedEndpoints(rsa->admin, &imported);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK_EQUAL(0, arrayList_size(imported));
-
- double result = 0;
- rc = calc->add(calc->calculator, 2.0, 5.0, &result);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK_EQUAL(7.0, result);
-
- arrayList_destroy(imported);
- arrayList_destroy(exported);
- }
-
- static void testExportService(void) {
- int rc = 0;
- const char *calcId = NULL;
- array_list_pt regs = NULL;
-
- rc = serviceReference_getProperty(calcRef, (char *)"service.id", &calcId);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = rsa->exportService(rsa->admin, (char*)calcId, NULL, ®s);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- CHECK_EQUAL(1, arrayList_size(regs));
-
- rc = rsa->exportRegistration_close(rsa->admin,(export_registration_pt)(arrayList_get(regs,0)));
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- }
-
- static void testImportService(void) {
- int rc = 0;
- import_registration_pt reg = NULL;
- endpoint_description_pt endpoint = NULL;
-
- properties_pt props = properties_create();
- properties_set(props, (char *)OSGI_RSA_ENDPOINT_SERVICE_ID, (char *)"42");
- properties_set(props, (char *)OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, (char *)"eec5404d-51d0-47ef-8d86-c825a8beda42");
- properties_set(props, (char *)OSGI_RSA_ENDPOINT_ID, (char *)"eec5404d-51d0-47ef-8d86-c825a8beda42-42");
- properties_set(props, (char *)OSGI_FRAMEWORK_OBJECTCLASS,(char *)"org.apache.celix.Example");
- properties_set(props, (char *)"service.version",(char *)"1.0.0"); //TODO find out standard in osgi spec
-
- rc = endpointDescription_create(props, &endpoint);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = rsa->importService(rsa->admin, endpoint, ®);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(reg != NULL);
-
- service_reference_pt ref = NULL;
- rc = bundleContext_getServiceReference(context, (char *)"org.apache.celix.Example", &ref);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(ref != NULL);
-
- rc = bundleContext_ungetServiceReference(context, ref);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = endpointDescription_destroy(endpoint);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- /* Cannot test. uses requesting bundles descriptor
- void *service = NULL;
- rc = bundleContext_getService(context, ref, &service);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(service != NULL);
- */
- }
-
- static void testBundles(void) {
- array_list_pt bundles = NULL;
-
- int rc = bundleContext_getBundles(context, &bundles);
- CHECK_EQUAL(0, rc);
- CHECK_EQUAL(3, arrayList_size(bundles)); //framework, rsa_dfi & calc
-
- /*
- int size = arrayList_size(bundles);
- int i;
- for (i = 0; i < size; i += 1) {
- bundle_pt bundle = NULL;
- module_pt module = NULL;
- char *name = NULL;
-
- bundle = (bundle_pt) arrayList_get(bundles, i);
- bundle_getCurrentModule(bundle, &module);
- module_getSymbolicName(module, &name);
- printf("got bundle with symbolic name '%s'", name);
- }*/
-
- arrayList_destroy(bundles);
- }
-
-}
-
-
-TEST_GROUP(RsaDfiTests) {
- void setup() {
- setupFm();
- }
-
- void teardown() {
- teardownFm();
- }
-};
-
-TEST(RsaDfiTests, InfoTest) {
- testServices();
-}
-
-TEST(RsaDfiTests, ExportService) {
- testExportService();
-}
-
-TEST(RsaDfiTests, ImportService) {
- testImportService();
-}
-
-TEST(RsaDfiTests, TestBundles) {
- testBundles();
-}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa_tst/run_tests.cpp
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/run_tests.cpp b/remote_services/remote_service_admin_dfi/rsa_tst/run_tests.cpp
deleted file mode 100644
index b5fd502..0000000
--- a/remote_services/remote_service_admin_dfi/rsa_tst/run_tests.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-
-#include <CppUTest/TestHarness.h>
-#include "CppUTest/CommandLineTestRunner.h"
-
-int main(int argc, char** argv) {
- return RUN_ALL_TESTS(argc, argv);
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/rsa_tst/server.properties.in
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/rsa_tst/server.properties.in b/remote_services/remote_service_admin_dfi/rsa_tst/server.properties.in
deleted file mode 100644
index 707c7e6..0000000
--- a/remote_services/remote_service_admin_dfi/rsa_tst/server.properties.in
+++ /dev/null
@@ -1,23 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-cosgi.auto.start.1=@rsa_bundle_file@ @calc_bundle_file@ @discovery_configured_bundle_file@ @topology_manager_bundle_file@
-LOGHELPER_ENABLE_STDOUT_FALLBACK=true
-RSA_PORT=50882
-DISCOVERY_CFG_SERVER_PORT=50992
-org.osgi.framework.storage.clean=onFirstInit
-org.osgi.framework.storage=.cacheServer
-DISCOVERY_CFG_POLL_INTERVAL=1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/src/dfi_utils.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/src/dfi_utils.c b/remote_services/remote_service_admin_dfi/src/dfi_utils.c
new file mode 100644
index 0000000..631152d
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/src/dfi_utils.c
@@ -0,0 +1,108 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include "dfi_utils.h"
+#include <stdlib.h>
+#include <unistd.h>
+
+static celix_status_t dfi_findFileForFramework(bundle_context_pt context, const char *fileName, FILE **out) {
+ celix_status_t status;
+
+ char pwd[1024];
+ char path[1024];
+ const char *extPath = NULL;
+
+ status = bundleContext_getProperty(context, "CELIX_FRAMEWORK_EXTENDER_PATH", &extPath);
+ if (status != CELIX_SUCCESS || extPath == NULL) {
+ getcwd(pwd, sizeof(pwd));
+ extPath = pwd;
+ }
+
+ snprintf(path, sizeof(path), "%s/%s", extPath, fileName);
+
+ if (status == CELIX_SUCCESS) {
+ FILE *df = fopen(path, "r");
+ if (df == NULL) {
+ status = CELIX_FILE_IO_EXCEPTION;
+ } else {
+ *out = df;
+ }
+ }
+
+ return status;
+}
+
+static celix_status_t dfi_findFileForBundle(bundle_pt bundle, const char *fileName, FILE **out) {
+ celix_status_t status;
+
+ //Checking if descriptor is in root dir of bundle
+ char *path = NULL;
+ status = bundle_getEntry(bundle, fileName, &path);
+
+ char metaInfFileName[512];
+ if (status != CELIX_SUCCESS || path == NULL) {
+ free(path);
+ //Checking if descriptor is in META-INF/descriptors
+ snprintf(metaInfFileName, sizeof(metaInfFileName), "META-INF/descriptors/%s", fileName);
+ status = bundle_getEntry(bundle, metaInfFileName, &path);
+ }
+
+ if (status != CELIX_SUCCESS || path == NULL) {
+ free(path);
+ //Checking if descriptor is in META-INF/descriptors/services
+ snprintf(metaInfFileName, sizeof(metaInfFileName), "META-INF/descriptors/services/%s", fileName);
+ status = bundle_getEntry(bundle, metaInfFileName, &path);
+ }
+
+
+ if (status == CELIX_SUCCESS && path != NULL) {
+ FILE *df = fopen(path, "r");
+ if (df == NULL) {
+ status = CELIX_FILE_IO_EXCEPTION;
+ } else {
+ *out = df;
+ }
+
+ }
+
+ free(path);
+ return status;
+}
+
+celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out) {
+ celix_status_t status;
+ char fileName[128];
+
+ snprintf(fileName, 128, "%s.descriptor", name);
+
+ long id;
+ status = bundle_getBundleId(bundle, &id);
+
+ if (status == CELIX_SUCCESS) {
+ if (id == 0) {
+ //framework bundle
+ status = dfi_findFileForFramework(context, fileName, out);
+ } else {
+ //normal bundle
+ status = dfi_findFileForBundle(bundle, fileName, out);
+ }
+ }
+
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/src/dfi_utils.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/src/dfi_utils.h b/remote_services/remote_service_admin_dfi/src/dfi_utils.h
new file mode 100644
index 0000000..cec8aa1
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/src/dfi_utils.h
@@ -0,0 +1,30 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+#ifndef DFI_UTILS_H_
+#define DFI_UTILS_H_
+
+#include "bundle.h"
+#include "bundle_context.h"
+#include <stdio.h>
+#include "celix_errno.h"
+
+
+celix_status_t dfi_findDescriptor(bundle_context_pt context, bundle_pt bundle, const char *name, FILE **out);
+
+#endif
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c
new file mode 100644
index 0000000..b83b5a8
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c
@@ -0,0 +1,251 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <jansson.h>
+#include <dyn_interface.h>
+#include <json_serializer.h>
+#include <remote_constants.h>
+#include <remote_service_admin.h>
+#include <service_tracker_customizer.h>
+#include <service_tracker.h>
+#include <json_rpc.h>
+#include "constants.h"
+#include "export_registration_dfi.h"
+#include "dfi_utils.h"
+
+struct export_reference {
+ endpoint_description_pt endpoint; //owner
+ service_reference_pt reference;
+};
+
+struct export_registration {
+ bundle_context_pt context;
+ struct export_reference exportReference;
+ char *servId;
+ dyn_interface_type *intf; //owner
+ service_tracker_pt tracker;
+
+ celix_thread_mutex_t mutex;
+ void *service; //protected by mutex
+
+ //TODO add tracker and lock
+ bool closed;
+};
+
+static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service);
+static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service);
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *out) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ const char *servId = NULL;
+ status = serviceReference_getProperty(reference, "service.id", &servId);
+ if (status != CELIX_SUCCESS) {
+ logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Cannot find service.id for ref");
+ }
+
+ export_registration_pt reg = NULL;
+ if (status == CELIX_SUCCESS) {
+ reg = calloc(1, sizeof(*reg));
+ if (reg == NULL) {
+ status = CELIX_ENOMEM;
+ }
+ }
+
+
+ if (status == CELIX_SUCCESS) {
+ reg->context = context;
+ reg->exportReference.endpoint = endpoint;
+ reg->exportReference.reference = reference;
+ reg->closed = false;
+
+ celixThreadMutex_create(®->mutex, NULL);
+ }
+
+ const char *exports = NULL;
+ CELIX_DO_IF(status, serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports));
+
+ bundle_pt bundle = NULL;
+ CELIX_DO_IF(status, serviceReference_getBundle(reference, &bundle));
+
+ FILE *descriptor = NULL;
+ if (status == CELIX_SUCCESS) {
+ status = dfi_findDescriptor(context, bundle, exports, &descriptor);
+ }
+
+ if (status != CELIX_SUCCESS || descriptor == NULL) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Cannot find/open descriptor for '%s'", exports);
+ }
+
+ if (status == CELIX_SUCCESS) {
+ int rc = dynInterface_parse(descriptor, ®->intf);
+ fclose(descriptor);
+ if (rc != 0) {
+ status = CELIX_BUNDLE_EXCEPTION;
+ logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "RSA: Error parsing service descriptor.");
+ }
+ else{
+ /* Add the interface version as a property in the properties_map */
+ char* intfVersion = NULL;
+ dynInterface_getVersionString(reg->intf, &intfVersion);
+ const char *serviceVersion = properties_get(endpoint->properties,(char*) CELIX_FRAMEWORK_SERVICE_VERSION);
+ if(serviceVersion!=NULL){
+ if(strcmp(serviceVersion,intfVersion)!=0){
+ logHelper_log(helper, OSGI_LOGSERVICE_WARNING, "Service version (%s) and interface version from the descriptor (%s) are not the same!",serviceVersion,intfVersion);
+ }
+ }
+ else{
+ properties_set(endpoint->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION, intfVersion);
+ }
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ service_tracker_customizer_pt cust = NULL;
+ status = serviceTrackerCustomizer_create(reg, NULL, (void *) exportRegistration_addServ, NULL,
+ (void *) exportRegistration_removeServ, &cust);
+ if (status == CELIX_SUCCESS) {
+ char filter[32];
+ snprintf(filter, 32, "(service.id=%s)", servId);
+ status = serviceTracker_createWithFilter(reg->context, filter, cust, ®->tracker);
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ *out = reg;
+ } else {
+ logHelper_log(helper, OSGI_LOGSERVICE_ERROR, "Error creating export registration");
+ exportRegistration_destroy(reg);
+ }
+
+ return status;
+}
+
+celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **responseOut, int *responseLength) {
+ int status = CELIX_SUCCESS;
+
+ //printf("calling for '%s'\n");
+
+ *responseLength = -1;
+ celixThreadMutex_lock(&export->mutex);
+ status = jsonRpc_call(export->intf, export->service, data, responseOut);
+ celixThreadMutex_unlock(&export->mutex);
+
+ return status;
+}
+
+void exportRegistration_destroy(export_registration_pt reg) {
+ if (reg != NULL) {
+ if (reg->intf != NULL) {
+ dyn_interface_type *intf = reg->intf;
+ reg->intf = NULL;
+ dynInterface_destroy(intf);
+ }
+
+ if (reg->exportReference.endpoint != NULL) {
+ endpoint_description_pt ep = reg->exportReference.endpoint;
+ reg->exportReference.endpoint = NULL;
+ endpointDescription_destroy(ep);
+ }
+ if (reg->tracker != NULL) {
+ serviceTracker_destroy(reg->tracker);
+ }
+ celixThreadMutex_destroy(®->mutex);
+
+ free(reg);
+ }
+}
+
+celix_status_t exportRegistration_start(export_registration_pt reg) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ serviceTracker_open(reg->tracker);
+ return status;
+}
+
+
+celix_status_t exportRegistration_stop(export_registration_pt reg) {
+ celix_status_t status = CELIX_SUCCESS;
+ if (status == CELIX_SUCCESS) {
+ status = bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference);
+ serviceTracker_close(reg->tracker);
+ }
+ return status;
+}
+
+static void exportRegistration_addServ(export_registration_pt reg, service_reference_pt ref, void *service) {
+ celixThreadMutex_lock(®->mutex);
+ reg->service = service;
+ celixThreadMutex_unlock(®->mutex);
+}
+
+static void exportRegistration_removeServ(export_registration_pt reg, service_reference_pt ref, void *service) {
+ celixThreadMutex_lock(®->mutex);
+ if (reg->service == service) {
+ reg->service = NULL;
+ }
+ celixThreadMutex_unlock(®->mutex);
+}
+
+
+celix_status_t exportRegistration_close(export_registration_pt reg) {
+ celix_status_t status = CELIX_SUCCESS;
+ exportRegistration_stop(reg);
+ return status;
+}
+
+
+celix_status_t exportRegistration_getException(export_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ //TODO
+ return status;
+}
+
+celix_status_t exportRegistration_getExportReference(export_registration_pt registration, export_reference_pt *out) {
+ celix_status_t status = CELIX_SUCCESS;
+ export_reference_pt ref = calloc(1, sizeof(*ref));
+ if (ref != NULL) {
+ ref->endpoint = registration->exportReference.endpoint;
+ ref->reference = registration->exportReference.reference;
+ } else {
+ status = CELIX_ENOMEM;
+ }
+
+ if (status == CELIX_SUCCESS) {
+ *out = ref;
+ }
+
+ return status;
+}
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
+ celix_status_t status = CELIX_SUCCESS;
+ *endpoint = reference->endpoint;
+ return status;
+}
+
+celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *ref) {
+ celix_status_t status = CELIX_SUCCESS;
+ *ref = reference->reference;
+ return status;
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/remote_service_admin_dfi/src/export_registration_dfi.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/src/export_registration_dfi.h b/remote_services/remote_service_admin_dfi/src/export_registration_dfi.h
new file mode 100644
index 0000000..93f37ba
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/src/export_registration_dfi.h
@@ -0,0 +1,38 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef CELIX_EXPORT_REGISTRATION_DFI_H
+#define CELIX_EXPORT_REGISTRATION_DFI_H
+
+
+#include "export_registration.h"
+#include "log_helper.h"
+#include "endpoint_description.h"
+
+celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *registration);
+celix_status_t exportRegistration_close(export_registration_pt registration);
+void exportRegistration_destroy(export_registration_pt registration);
+
+celix_status_t exportRegistration_start(export_registration_pt registration);
+celix_status_t exportRegistration_stop(export_registration_pt registration);
+
+celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **response, int *responseLength);
+
+
+#endif //CELIX_EXPORT_REGISTRATION_DFI_H
[4/8] celix git commit: CELIX-417: Refactors CMake usage for the RSA
bundles
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/src/civetweb.c
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/src/civetweb.c b/remote_services/discovery_common/src/civetweb.c
deleted file mode 100644
index a6093b7..0000000
--- a/remote_services/discovery_common/src/civetweb.c
+++ /dev/null
@@ -1,7907 +0,0 @@
- /* Copyright (c) 2013-2015 the Civetweb developers
- * Copyright (c) 2004-2013 Sergey Lyubka
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#if defined(_WIN32)
-#if !defined(_CRT_SECURE_NO_WARNINGS)
-#define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005 */
-#endif
-#else
-#ifdef __linux__
-#define _XOPEN_SOURCE 600 /* For flockfile() on Linux */
-#endif
-#ifndef _LARGEFILE_SOURCE
-#define _LARGEFILE_SOURCE /* For fseeko(), ftello() */
-#endif
-#ifndef _FILE_OFFSET_BITS
-#define _FILE_OFFSET_BITS 64 /* Use 64-bit file offsets by default */
-#endif
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS /* <inttypes.h> wants this for C++ */
-#endif
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS /* C++ wants that for INT64_MAX */
-#endif
-#endif
-
-#if defined (_MSC_VER)
-/* 'type cast' : conversion from 'int' to 'HANDLE' of greater size */
-#pragma warning (disable : 4306 )
-/* conditional expression is constant: introduced by FD_SET(..) */
-#pragma warning (disable : 4127)
-/* non-constant aggregate initializer: issued due to missing C99 support */
-#pragma warning (disable : 4204)
-#endif
-
-/* Disable WIN32_LEAN_AND_MEAN.
- This makes windows.h always include winsock2.h */
-#if defined(WIN32_LEAN_AND_MEAN)
-#undef WIN32_LEAN_AND_MEAN
-#endif
-
-#if defined USE_IPV6 && defined(_WIN32)
-#include <ws2tcpip.h>
-#endif
-
-#if defined(__SYMBIAN32__)
-#define NO_SSL /* SSL is not supported */
-#define NO_CGI /* CGI is not supported */
-#define PATH_MAX FILENAME_MAX
-#endif /* __SYMBIAN32__ */
-
-#ifndef IGNORE_UNUSED_RESULT
-#define IGNORE_UNUSED_RESULT(a) (void)((a) && 1)
-#endif
-
-#ifndef _WIN32_WCE /* Some ANSI #includes are not available on Windows CE */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <signal.h>
-#include <fcntl.h>
-#endif /* !_WIN32_WCE */
-
-#include <time.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-
-#ifndef MAX_WORKER_THREADS
-#define MAX_WORKER_THREADS (1024*64)
-#endif
-
-#if defined(_WIN32) && !defined(__SYMBIAN32__) /* Windows specific */
-#if defined(_MSC_VER) && _MSC_VER <= 1400
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400 /* To make it link in VS2005 */
-#endif
-#include <windows.h>
-typedef const char * SOCK_OPT_TYPE;
-
-#ifndef PATH_MAX
-#define PATH_MAX MAX_PATH
-#endif
-
-#ifndef _IN_PORT_T
-#ifndef in_port_t
-#define in_port_t u_short
-#endif
-#endif
-
-#ifndef _WIN32_WCE
-#include <process.h>
-#include <direct.h>
-#include <io.h>
-#else /* _WIN32_WCE */
-#define NO_CGI /* WinCE has no pipes */
-
-typedef long off_t;
-
-#define errno GetLastError()
-#define strerror(x) _ultoa(x, (char *) _alloca(sizeof(x) *3 ), 10)
-#endif /* _WIN32_WCE */
-
-#define MAKEUQUAD(lo, hi) ((uint64_t)(((uint32_t)(lo)) | \
- ((uint64_t)((uint32_t)(hi))) << 32))
-#define RATE_DIFF 10000000 /* 100 nsecs */
-#define EPOCH_DIFF MAKEUQUAD(0xd53e8000, 0x019db1de)
-#define SYS2UNIX_TIME(lo, hi) \
- (time_t) ((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)
-
-/* Visual Studio 6 does not know __func__ or __FUNCTION__
- The rest of MS compilers use __FUNCTION__, not C99 __func__
- Also use _strtoui64 on modern M$ compilers */
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define STRX(x) #x
-#define STR(x) STRX(x)
-#define __func__ __FILE__ ":" STR(__LINE__)
-#define strtoull(x, y, z) (unsigned __int64) _atoi64(x)
-#define strtoll(x, y, z) _atoi64(x)
-#else
-#define __func__ __FUNCTION__
-#define strtoull(x, y, z) _strtoui64(x, y, z)
-#define strtoll(x, y, z) _strtoi64(x, y, z)
-#endif /* _MSC_VER */
-
-#define ERRNO GetLastError()
-#define NO_SOCKLEN_T
-#define SSL_LIB "ssleay32.dll"
-#define CRYPTO_LIB "libeay32.dll"
-#define O_NONBLOCK 0
-#define W_OK (2) /* http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx */
-#if !defined(EWOULDBLOCK)
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#endif /* !EWOULDBLOCK */
-#define _POSIX_
-#define INT64_FMT "I64d"
-
-#define WINCDECL __cdecl
-#define SHUT_WR 1
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#define access _access
-#define mg_sleep(x) Sleep(x)
-
-#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
-#ifndef popen
-#define popen(x, y) _popen(x, y)
-#endif
-#ifndef pclose
-#define pclose(x) _pclose(x)
-#endif
-#define close(x) _close(x)
-#define dlsym(x,y) GetProcAddress((HINSTANCE) (x), (y))
-#define RTLD_LAZY 0
-#define fseeko(x, y, z) _lseeki64(_fileno(x), (y), (z))
-#define fdopen(x, y) _fdopen((x), (y))
-#define write(x, y, z) _write((x), (y), (unsigned) z)
-#define read(x, y, z) _read((x), (y), (unsigned) z)
-#define flockfile(x) EnterCriticalSection(&global_log_file_lock)
-#define funlockfile(x) LeaveCriticalSection(&global_log_file_lock)
-#define sleep(x) Sleep((x) * 1000)
-#define rmdir(x) _rmdir(x)
-
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
-#define USE_TIMERS
-#endif
-
-#if !defined(va_copy)
-#define va_copy(x, y) x = y
-#endif /* !va_copy MINGW #defines va_copy */
-
-#if !defined(fileno)
-#define fileno(x) _fileno(x)
-#endif /* !fileno MINGW #defines fileno */
-
-typedef HANDLE pthread_mutex_t;
-typedef DWORD pthread_key_t;
-typedef HANDLE pthread_t;
-typedef struct {
- CRITICAL_SECTION threadIdSec;
- int waitingthreadcount; /* The number of threads queued. */
- pthread_t *waitingthreadhdls; /* The thread handles. */
-} pthread_cond_t;
-
-#ifndef __clockid_t_defined
-typedef DWORD clockid_t;
-#endif
-#ifndef CLOCK_MONOTONIC
-#define CLOCK_MONOTONIC (1)
-#endif
-#ifndef CLOCK_REALTIME
-#define CLOCK_REALTIME (2)
-#endif
-
-#ifndef _TIMESPEC_DEFINED
-struct timespec {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* nanoseconds */
-};
-#endif
-
-#define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */
-
-static int pthread_mutex_lock(pthread_mutex_t *);
-static int pthread_mutex_unlock(pthread_mutex_t *);
-static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len);
-struct file;
-static char *mg_fgets(char *buf, size_t size, struct file *filep, char **p);
-
-#if defined(HAVE_STDINT)
-#include <stdint.h>
-#else
-typedef unsigned int uint32_t;
-typedef unsigned short uint16_t;
-typedef unsigned __int64 uint64_t;
-typedef __int64 int64_t;
-#define INT64_MAX 9223372036854775807
-#endif /* HAVE_STDINT */
-
-/* POSIX dirent interface */
-struct dirent {
- char d_name[PATH_MAX];
-};
-
-typedef struct DIR {
- HANDLE handle;
- WIN32_FIND_DATAW info;
- struct dirent result;
-} DIR;
-
-#if !defined(USE_IPV6) && defined(_WIN32)
-#ifndef HAVE_POLL
-struct pollfd {
- SOCKET fd;
- short events;
- short revents;
-};
-#define POLLIN 1
-#endif
-#endif
-
-/* Mark required libraries */
-#ifdef _MSC_VER
-#pragma comment(lib, "Ws2_32.lib")
-#endif
-
-#else /* UNIX specific */
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <sys/utsname.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <netdb.h>
-typedef const void * SOCK_OPT_TYPE;
-
-//#if defined(ANDROID)
-typedef unsigned short int in_port_t;
-//#endif
-
-#include <pwd.h>
-#include <unistd.h>
-#include <dirent.h>
-#if !defined(NO_SSL_DL) && !defined(NO_SSL)
-#include <dlfcn.h>
-#endif
-#include <pthread.h>
-#if defined(__MACH__)
-#define SSL_LIB "libssl.dylib"
-#define CRYPTO_LIB "libcrypto.dylib"
-#else
-#if !defined(SSL_LIB)
-#define SSL_LIB "libssl.so"
-#endif
-#if !defined(CRYPTO_LIB)
-#define CRYPTO_LIB "libcrypto.so"
-#endif
-#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif /* O_BINARY */
-#define closesocket(a) close(a)
-#define mg_mkdir(x, y) mkdir(x, y)
-#define mg_remove(x) remove(x)
-#define mg_sleep(x) usleep((x) * 1000)
-#define ERRNO errno
-#define INVALID_SOCKET (-1)
-#define INT64_FMT PRId64
-typedef int SOCKET;
-#define WINCDECL
-
-#endif /* End of Windows and UNIX specific includes */
-
-#ifdef _WIN32
-static CRITICAL_SECTION global_log_file_lock;
-static DWORD pthread_self(void)
-{
- return GetCurrentThreadId();
-}
-
-int pthread_key_create(pthread_key_t *key, void (*_must_be_zero)(void*) /* destructor function not supported for windows */)
-{
- assert(_must_be_zero == NULL);
- if ((key!=0) && (_must_be_zero == NULL)) {
- *key = TlsAlloc();
- return (*key != TLS_OUT_OF_INDEXES) ? 0 : -1;
- }
- return -2;
-}
-
-int pthread_key_delete(pthread_key_t key)
-{
- return TlsFree(key) ? 0 : 1;
-}
-
-int pthread_setspecific(pthread_key_t key, void * value)
-{
- return TlsSetValue(key, value) ? 0 : 1;
-}
-
-void *pthread_getspecific(pthread_key_t key)
-{
- return TlsGetValue(key);
-}
-#endif /* _WIN32 */
-
-
-#include "civetweb.h"
-
-#define PASSWORDS_FILE_NAME ".htpasswd"
-#define CGI_ENVIRONMENT_SIZE 4096
-#define MAX_CGI_ENVIR_VARS 64
-#define MG_BUF_LEN 8192
-#ifndef MAX_REQUEST_SIZE
-#define MAX_REQUEST_SIZE 16384
-#endif
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
-
-#if !defined(DEBUG_TRACE)
-#if defined(CWDEBUG)
-
-static void DEBUG_TRACE_FUNC(const char *func, unsigned line, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(3, 4);
-
-static void DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...) {
-
- va_list args;
- flockfile(stdout);
- printf("*** %lu.%p.%s.%u: ",
- (unsigned long) time(NULL), (void *) pthread_self(),
- func, line);
- va_start(args, fmt);
- vprintf(fmt, args);
- va_end(args);
- putchar('\n');
- fflush(stdout);
- funlockfile(stdout);
-}
-
-#define DEBUG_TRACE(fmt, ...) DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__)
-
-#else
-#define DEBUG_TRACE(fmt, ...)
-#endif /* CWDEBUG */
-#endif /* DEBUG_TRACE */
-
-#if defined(MEMORY_DEBUGGING)
-static unsigned long blockCount = 0;
-static unsigned long totalMemUsed = 0;
-
-static void * mg_malloc_ex(size_t size, const char * file, unsigned line) {
-
- void * data = malloc(size + sizeof(size_t));
- void * memory = 0;
- char mallocStr[256];
-
- if (data) {
- *(size_t*)data = size;
- totalMemUsed += size;
- blockCount++;
- memory = (void *)(((char*)data)+sizeof(size_t));
- }
-
- sprintf(mallocStr, "MEM: %p %5lu alloc %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
- OutputDebugStringA(mallocStr);
-#else
- DEBUG_TRACE("%s", mallocStr);
-#endif
-
- return memory;
-}
-
-static void * mg_calloc_ex(size_t count, size_t size, const char * file, unsigned line) {
-
- void * data = mg_malloc_ex(size*count, file, line);
- if (data) memset(data, 0, size);
-
- return data;
-}
-
-static void mg_free_ex(void * memory, const char * file, unsigned line) {
-
- char mallocStr[256];
- void * data = (void *)(((char*)memory)-sizeof(size_t));
- size_t size;
-
- if (memory) {
- size = *(size_t*)data;
- totalMemUsed -= size;
- blockCount--;
- sprintf(mallocStr, "MEM: %p %5lu free %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
- OutputDebugStringA(mallocStr);
-#else
- DEBUG_TRACE("%s", mallocStr);
-#endif
-
- free(data);
- }
-}
-
-static void * mg_realloc_ex(void * memory, size_t newsize, const char * file, unsigned line) {
-
- char mallocStr[256];
- void * data;
- void * _realloc;
- size_t oldsize;
-
- if (newsize) {
- if (memory) {
- data = (void *)(((char*)memory)-sizeof(size_t));
- oldsize = *(size_t*)data;
- _realloc = realloc(data, newsize+sizeof(size_t));
- if (_realloc) {
- data = _realloc;
- totalMemUsed -= oldsize;
- sprintf(mallocStr, "MEM: %p %5lu r-free %7lu %4lu --- %s:%u\n", memory, (unsigned long)oldsize, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
- OutputDebugStringA(mallocStr);
-#else
- DEBUG_TRACE("%s", mallocStr);
-#endif
- totalMemUsed += newsize;
- sprintf(mallocStr, "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n", memory, (unsigned long)newsize, totalMemUsed, blockCount, file, line);
-#if defined(_WIN32)
- OutputDebugStringA(mallocStr);
-#else
- DEBUG_TRACE("%s", mallocStr);
-#endif
- *(size_t*)data = newsize;
- data = (void *)(((char*)data)+sizeof(size_t));
- } else {
-#if defined(_WIN32)
- OutputDebugStringA("MEM: realloc failed\n");
-#else
- DEBUG_TRACE("%s", "MEM: realloc failed\n");
-#endif
- return _realloc;
- }
- } else {
- data = mg_malloc_ex(newsize, file, line);
- }
- } else {
- data = 0;
- mg_free_ex(memory, file, line);
- }
-
- return data;
-}
-
-#define mg_malloc(a) mg_malloc_ex(a, __FILE__, __LINE__)
-#define mg_calloc(a,b) mg_calloc_ex(a, b, __FILE__, __LINE__)
-#define mg_realloc(a, b) mg_realloc_ex(a, b, __FILE__, __LINE__)
-#define mg_free(a) mg_free_ex(a, __FILE__, __LINE__)
-
-#else
-static __inline void * mg_malloc(size_t a) {return malloc(a);}
-static __inline void * mg_calloc(size_t a, size_t b) {return calloc(a, b);}
-static __inline void * mg_realloc(void * a, size_t b) {return realloc(a, b);}
-static __inline void mg_free(void * a) {free(a);}
-#endif
-
-/* This following lines are just meant as a reminder to use the mg-functions for memory management */
-#ifdef malloc
- #undef malloc
-#endif
-#ifdef calloc
- #undef calloc
-#endif
-#ifdef realloc
- #undef realloc
-#endif
-#ifdef free
- #undef free
-#endif
-#define malloc DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc
-#define calloc DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc
-#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc
-#define free DO_NOT_USE_THIS_FUNCTION__USE_mg_free
-
-
-#define MD5_STATIC static
-#include "md5.inl"
-
-/* Darwin prior to 7.0 and Win32 do not have socklen_t */
-#ifdef NO_SOCKLEN_T
-typedef int socklen_t;
-#endif /* NO_SOCKLEN_T */
-#define _DARWIN_UNLIMITED_SELECT
-
-#define IP_ADDR_STR_LEN 50 /* IPv6 hex string is 46 chars */
-
-#if !defined(MSG_NOSIGNAL)
-#define MSG_NOSIGNAL 0
-#endif
-
-#if !defined(SOMAXCONN)
-#define SOMAXCONN 100
-#endif
-
-#if !defined(PATH_MAX)
-#define PATH_MAX 4096
-#endif
-
-/* Size of the accepted socket queue */
-#if !defined(MGSQLEN)
-#define MGSQLEN 20
-#endif
-
-#if defined(NO_SSL_DL)
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#else
-/* SSL loaded dynamically from DLL.
- I put the prototypes here to be independent from OpenSSL source
- installation. */
-
-typedef struct ssl_st SSL;
-typedef struct ssl_method_st SSL_METHOD;
-typedef struct ssl_ctx_st SSL_CTX;
-
-struct ssl_func {
- const char *name; /* SSL function name */
- void (*ptr)(void); /* Function pointer */
-};
-
-#define SSL_free (* (void (*)(SSL *)) ssl_sw[0].ptr)
-#define SSL_accept (* (int (*)(SSL *)) ssl_sw[1].ptr)
-#define SSL_connect (* (int (*)(SSL *)) ssl_sw[2].ptr)
-#define SSL_read (* (int (*)(SSL *, void *, int)) ssl_sw[3].ptr)
-#define SSL_write (* (int (*)(SSL *, const void *,int)) ssl_sw[4].ptr)
-#define SSL_get_error (* (int (*)(SSL *, int)) ssl_sw[5].ptr)
-#define SSL_set_fd (* (int (*)(SSL *, SOCKET)) ssl_sw[6].ptr)
-#define SSL_new (* (SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
-#define SSL_CTX_new (* (SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
-#define SSLv23_server_method (* (SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
-#define SSL_library_init (* (int (*)(void)) ssl_sw[10].ptr)
-#define SSL_CTX_use_PrivateKey_file (* (int (*)(SSL_CTX *, \
- const char *, int)) ssl_sw[11].ptr)
-#define SSL_CTX_use_certificate_file (* (int (*)(SSL_CTX *, \
- const char *, int)) ssl_sw[12].ptr)
-#define SSL_CTX_set_default_passwd_cb \
- (* (void (*)(SSL_CTX *, mg_callback_t)) ssl_sw[13].ptr)
-#define SSL_CTX_free (* (void (*)(SSL_CTX *)) ssl_sw[14].ptr)
-#define SSL_load_error_strings (* (void (*)(void)) ssl_sw[15].ptr)
-#define SSL_CTX_use_certificate_chain_file \
- (* (int (*)(SSL_CTX *, const char *)) ssl_sw[16].ptr)
-#define SSLv23_client_method (* (SSL_METHOD * (*)(void)) ssl_sw[17].ptr)
-#define SSL_pending (* (int (*)(SSL *)) ssl_sw[18].ptr)
-#define SSL_CTX_set_verify (* (void (*)(SSL_CTX *, int, int)) ssl_sw[19].ptr)
-#define SSL_shutdown (* (int (*)(SSL *)) ssl_sw[20].ptr)
-
-#define CRYPTO_num_locks (* (int (*)(void)) crypto_sw[0].ptr)
-#define CRYPTO_set_locking_callback \
- (* (void (*)(void (*)(int, int, const char *, int))) crypto_sw[1].ptr)
-#define CRYPTO_set_id_callback \
- (* (void (*)(unsigned long (*)(void))) crypto_sw[2].ptr)
-#define ERR_get_error (* (unsigned long (*)(void)) crypto_sw[3].ptr)
-#define ERR_error_string (* (char * (*)(unsigned long,char *)) crypto_sw[4].ptr)
-
-/* set_ssl_option() function updates this array.
- It loads SSL library dynamically and changes NULLs to the actual addresses
- of respective functions. The macros above (like SSL_connect()) are really
- just calling these functions indirectly via the pointer. */
-static struct ssl_func ssl_sw[] = {
- {"SSL_free", NULL},
- {"SSL_accept", NULL},
- {"SSL_connect", NULL},
- {"SSL_read", NULL},
- {"SSL_write", NULL},
- {"SSL_get_error", NULL},
- {"SSL_set_fd", NULL},
- {"SSL_new", NULL},
- {"SSL_CTX_new", NULL},
- {"SSLv23_server_method", NULL},
- {"SSL_library_init", NULL},
- {"SSL_CTX_use_PrivateKey_file", NULL},
- {"SSL_CTX_use_certificate_file",NULL},
- {"SSL_CTX_set_default_passwd_cb",NULL},
- {"SSL_CTX_free", NULL},
- {"SSL_load_error_strings", NULL},
- {"SSL_CTX_use_certificate_chain_file", NULL},
- {"SSLv23_client_method", NULL},
- {"SSL_pending", NULL},
- {"SSL_CTX_set_verify", NULL},
- {"SSL_shutdown", NULL},
- {NULL, NULL}
-};
-
-/* Similar array as ssl_sw. These functions could be located in different
- lib. */
-#if !defined(NO_SSL)
-static struct ssl_func crypto_sw[] = {
- {"CRYPTO_num_locks", NULL},
- {"CRYPTO_set_locking_callback", NULL},
- {"CRYPTO_set_id_callback", NULL},
- {"ERR_get_error", NULL},
- {"ERR_error_string", NULL},
- {NULL, NULL}
-};
-#endif /* NO_SSL */
-#endif /* NO_SSL_DL */
-
-static const char *month_names[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-/* Unified socket address. For IPv6 support, add IPv6 address structure
- in the union u. */
-union usa {
- struct sockaddr sa;
- struct sockaddr_in sin;
-#if defined(USE_IPV6)
- struct sockaddr_in6 sin6;
-#endif
-};
-
-/* Describes a string (chunk of memory). */
-struct vec {
- const char *ptr;
- size_t len;
-};
-
-struct file {
- int is_directory;
- time_t modification_time;
- int64_t size;
- FILE *fp;
- const char *membuf; /* Non-NULL if file data is in memory */
- /* set to 1 if the content is gzipped
- in which case we need a content-encoding: gzip header */
- int gzipped;
-};
-#define STRUCT_FILE_INITIALIZER {0, 0, 0, NULL, NULL, 0}
-
-/* Describes listening socket, or socket which was accept()-ed by the master
- thread and queued for future handling by the worker thread. */
-struct socket {
- SOCKET sock; /* Listening socket */
- union usa lsa; /* Local socket address */
- union usa rsa; /* Remote socket address */
- unsigned is_ssl:1; /* Is port SSL-ed */
- unsigned ssl_redir:1; /* Is port supposed to redirect everything to SSL
- port */
-};
-
-/* NOTE(lsm): this enum shoulds be in sync with the config_options below. */
-enum {
- CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER,
- PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS, THROTTLE,
- ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE,
- GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
- EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE,
- NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT,
- DECODE_URL,
-
-#if defined(USE_LUA)
- LUA_PRELOAD_FILE, LUA_SCRIPT_EXTENSIONS, LUA_SERVER_PAGE_EXTENSIONS,
-#endif
-#if defined(USE_WEBSOCKET)
- WEBSOCKET_ROOT,
-#endif
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
- LUA_WEBSOCKET_EXTENSIONS,
-#endif
- ACCESS_CONTROL_ALLOW_ORIGIN, ERROR_PAGES,
-
- NUM_OPTIONS
-};
-
-/* Config option name, config types, default value */
-static struct mg_option config_options[] = {
- {"cgi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.cgi$|**.pl$|**.php$"},
- {"cgi_environment", CONFIG_TYPE_STRING, NULL},
- {"put_delete_auth_file", CONFIG_TYPE_FILE, NULL},
- {"cgi_interpreter", CONFIG_TYPE_FILE, NULL},
- {"protect_uri", CONFIG_TYPE_STRING, NULL},
- {"authentication_domain", CONFIG_TYPE_STRING, "mydomain.com"},
- {"ssi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.shtml$|**.shtm$"},
- {"throttle", CONFIG_TYPE_STRING, NULL},
- {"access_log_file", CONFIG_TYPE_FILE, NULL},
- {"enable_directory_listing", CONFIG_TYPE_BOOLEAN, "yes"},
- {"error_log_file", CONFIG_TYPE_FILE, NULL},
- {"global_auth_file", CONFIG_TYPE_FILE, NULL},
- {"index_files", CONFIG_TYPE_STRING,
-#ifdef USE_LUA
- "index.xhtml,index.html,index.htm,index.lp,index.lsp,index.lua,index.cgi,index.shtml,index.php"},
-#else
- "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
-#endif
- {"enable_keep_alive", CONFIG_TYPE_BOOLEAN, "no"},
- {"access_control_list", CONFIG_TYPE_STRING, NULL},
- {"extra_mime_types", CONFIG_TYPE_STRING, NULL},
- {"listening_ports", CONFIG_TYPE_STRING, "8080"},
- {"document_root", CONFIG_TYPE_DIRECTORY, NULL},
- {"ssl_certificate", CONFIG_TYPE_FILE, NULL},
- {"num_threads", CONFIG_TYPE_NUMBER, "50"},
- {"run_as_user", CONFIG_TYPE_STRING, NULL},
- {"url_rewrite_patterns", CONFIG_TYPE_STRING, NULL},
- {"hide_files_patterns", CONFIG_TYPE_EXT_PATTERN, NULL},
- {"request_timeout_ms", CONFIG_TYPE_NUMBER, "30000"},
- {"decode_url", CONFIG_TYPE_BOOLEAN, "yes"},
-
-#if defined(USE_LUA)
- {"lua_preload_file", CONFIG_TYPE_FILE, NULL},
- {"lua_script_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
- {"lua_server_page_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lp$|**.lsp$"},
-#endif
-#if defined(USE_WEBSOCKET)
- {"websocket_root", CONFIG_TYPE_DIRECTORY, NULL},
-#endif
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
- {"lua_websocket_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
-#endif
- {"access_control_allow_origin", CONFIG_TYPE_STRING, "*"},
- {"error_pages", CONFIG_TYPE_DIRECTORY, NULL},
-
- {NULL, CONFIG_TYPE_UNKNOWN, NULL}
-};
-
-struct mg_request_handler_info {
- char *uri;
- size_t uri_len;
- mg_request_handler handler;
-
- void *cbdata;
- struct mg_request_handler_info *next;
-};
-
-struct mg_context {
- volatile int stop_flag; /* Should we stop event loop */
- SSL_CTX *ssl_ctx; /* SSL context */
- char *config[NUM_OPTIONS]; /* Civetweb configuration parameters */
- struct mg_callbacks callbacks; /* User-defined callback function */
- void *user_data; /* User-defined data */
- int context_type; /* 1 = server context, 2 = client context */
-
- struct socket *listening_sockets;
- in_port_t *listening_ports;
- int num_listening_sockets;
-
- volatile int num_threads; /* Number of threads */
- pthread_mutex_t thread_mutex; /* Protects (max|num)_threads */
- pthread_cond_t thread_cond; /* Condvar for tracking workers terminations */
-
- struct socket queue[MGSQLEN]; /* Accepted sockets */
- volatile int sq_head; /* Head of the socket queue */
- volatile int sq_tail; /* Tail of the socket queue */
- pthread_cond_t sq_full; /* Signaled when socket is produced */
- pthread_cond_t sq_empty; /* Signaled when socket is consumed */
- pthread_t masterthreadid; /* The master thread ID */
- int workerthreadcount; /* The amount of worker threads. */
- pthread_t *workerthreadids; /* The worker thread IDs */
-
- unsigned long start_time; /* Server start time, used for authentication */
- pthread_mutex_t nonce_mutex; /* Protects nonce_count */
- unsigned long nonce_count; /* Used nonces, used for authentication */
-
- char *systemName; /* What operating system is running */
-
- /* linked list of uri handlers */
- struct mg_request_handler_info *request_handlers;
-
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
- /* linked list of shared lua websockets */
- struct mg_shared_lua_websocket_list *shared_lua_websockets;
-#endif
-
-#ifdef USE_TIMERS
- struct ttimers * timers;
-#endif
-};
-
-struct mg_connection {
- struct mg_request_info request_info;
- struct mg_context *ctx;
- SSL *ssl; /* SSL descriptor */
- SSL_CTX *client_ssl_ctx; /* SSL context for client connections */
- struct socket client; /* Connected client */
- time_t birth_time; /* Time when request was received */
- int64_t num_bytes_sent; /* Total bytes sent to client */
- int64_t content_len; /* Content-Length header value */
- int64_t consumed_content; /* How many bytes of content have been read */
- char *buf; /* Buffer for received data */
- char *path_info; /* PATH_INFO part of the URL */
- int must_close; /* 1 if connection must be closed */
- int in_error_handler; /* 1 if in handler for user defined error pages */
- int buf_size; /* Buffer size */
- int request_len; /* Size of the request + headers in a buffer */
- int data_len; /* Total size of data in a buffer */
- int status_code; /* HTTP reply status code, e.g. 200 */
- int throttle; /* Throttling, bytes/sec. <= 0 means no throttle */
- time_t last_throttle_time; /* Last time throttled data was sent */
- int64_t last_throttle_bytes; /* Bytes sent this second */
- pthread_mutex_t mutex; /* Used by mg_lock_connection/mg_unlock_connection to ensure atomic transmissions for websockets */
-#if defined(USE_LUA) && defined(USE_WEBSOCKET)
- void * lua_websocket_state; /* Lua_State for a websocket connection */
-#endif
-};
-
-static pthread_key_t sTlsKey; /* Thread local storage index */
-static int sTlsInit = 0;
-
-struct mg_workerTLS {
- int is_master;
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
- HANDLE pthread_cond_helper_mutex;
-#endif
-};
-
-/* Directory entry */
-struct de {
- struct mg_connection *conn;
- char *file_name;
- struct file file;
-};
-
-#if defined(USE_WEBSOCKET)
-static int is_websocket_protocol(const struct mg_connection *conn);
-#else
-#define is_websocket_protocol(conn) (0)
-#endif
-
-int mg_atomic_inc(volatile int * addr)
-{
- int ret;
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
- ret = InterlockedIncrement((volatile unsigned int *) addr);
-#elif defined(__GNUC__)
- ret = __sync_add_and_fetch(addr, 1);
-#else
- ret = (++(*addr));
-#endif
- return ret;
-}
-
-int mg_atomic_dec(volatile int * addr)
-{
- int ret;
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
- ret = InterlockedDecrement((volatile unsigned int *) addr);
-#elif defined(__GNUC__)
- ret = __sync_sub_and_fetch(addr, 1);
-#else
- ret = (--(*addr));
-#endif
- return ret;
-}
-
-#if !defined(NO_THREAD_NAME)
-#if defined(_WIN32) && defined(_MSC_VER)
-/* Set the thread name for debugging purposes in Visual Studio
- http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
-*/
-#pragma pack(push,8)
-typedef struct tagTHREADNAME_INFO
-{
- DWORD dwType; /* Must be 0x1000. */
- LPCSTR szName; /* Pointer to name (in user addr space). */
- DWORD dwThreadID; /* Thread ID (-1=caller thread). */
- DWORD dwFlags; /* Reserved for future use, must be zero. */
-} THREADNAME_INFO;
-#pragma pack(pop)
-#elif defined(__linux__)
-#include <sys/prctl.h>
-#endif
-
-void mg_set_thread_name(const char* name)
-{
- char threadName[16]; /* Max. thread length in Linux/OSX/.. */
-
- if (snprintf(threadName, sizeof(threadName), "civetweb-%s", name)<0) return;
- threadName[sizeof(threadName)-1] = 0;
-
-#if defined(_WIN32)
-#if defined(_MSC_VER)
- /* Windows and Visual Studio Compiler */
- __try
- {
- THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = threadName;
- info.dwThreadID = -1;
- info.dwFlags = 0;
-
- RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
- }
- __except(EXCEPTION_EXECUTE_HANDLER)
- {
- }
-#elif defined(__MINGW32__)
- /* No option known to set thread name for MinGW */
-#endif
-#elif defined(__linux__)
- /* Linux */
- (void)prctl(PR_SET_NAME,threadName,0,0,0);
-#elif defined(__APPLE__) || defined(__MACH__)
- /* OS X (TODO: test) */
- (void)pthread_setname_np(threadName);
-#elif defined(BSD) || defined(__FreeBSD__) || defined(__OpenBSD__)
- /* BSD (TODO: test) */
- pthread_set_name_np(pthread_self(), threadName);
-#else
- /* POSIX */
- (void)pthread_setname_np(pthread_self(), threadName);
-#endif
-}
-#else /* !defined(NO_THREAD_NAME) */
-void mg_set_thread_name(const char* threadName) {}
-#endif
-
-#if defined(MG_LEGACY_INTERFACE)
-const char **mg_get_valid_option_names(void)
-{
- static const char * data[2 * sizeof(config_options) / sizeof(config_options[0])] = {0};
- int i;
-
- for (i=0; config_options[i].name != NULL; i++) {
- data[i * 2] = config_options[i].name;
- data[i * 2 + 1] = config_options[i].default_value;
- }
-
- return data;
-}
-#endif
-
-const struct mg_option *mg_get_valid_options(void)
-{
- return config_options;
-}
-
-
-static int is_file_in_memory(struct mg_connection *conn, const char *path,
- struct file *filep)
-{
- size_t size = 0;
- if ((filep->membuf = conn->ctx->callbacks.open_file == NULL ? NULL :
- conn->ctx->callbacks.open_file(conn, path, &size)) != NULL) {
- /* NOTE: override filep->size only on success. Otherwise, it might
- break constructs like if (!mg_stat() || !mg_fopen()) ... */
- filep->size = size;
- }
- return filep->membuf != NULL;
-}
-
-static int is_file_opened(const struct file *filep)
-{
- return filep->membuf != NULL || filep->fp != NULL;
-}
-
-static int mg_fopen(struct mg_connection *conn, const char *path,
- const char *mode, struct file *filep)
-{
- if (!is_file_in_memory(conn, path, filep)) {
-#ifdef _WIN32
- wchar_t wbuf[PATH_MAX], wmode[20];
- to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
- MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, ARRAY_SIZE(wmode));
- filep->fp = _wfopen(wbuf, wmode);
-#else
- filep->fp = fopen(path, mode);
-#endif
- }
-
- return is_file_opened(filep);
-}
-
-static void mg_fclose(struct file *filep)
-{
- if (filep != NULL && filep->fp != NULL) {
- fclose(filep->fp);
- }
-}
-
-static void mg_strlcpy(register char *dst, register const char *src, size_t n)
-{
- for (; *src != '\0' && n > 1; n--) {
- *dst++ = *src++;
- }
- *dst = '\0';
-}
-
-static int lowercase(const char *s)
-{
- return tolower(* (const unsigned char *) s);
-}
-
-int mg_strncasecmp(const char *s1, const char *s2, size_t len)
-{
- int diff = 0;
-
- if (len > 0)
- do {
- diff = lowercase(s1++) - lowercase(s2++);
- } while (diff == 0 && s1[-1] != '\0' && --len > 0);
-
- return diff;
-}
-
-static int mg_strcasecmp(const char *s1, const char *s2)
-{
- int diff;
-
- do {
- diff = lowercase(s1++) - lowercase(s2++);
- } while (diff == 0 && s1[-1] != '\0');
-
- return diff;
-}
-
-static char * mg_strndup(const char *ptr, size_t len)
-{
- char *p;
-
- if ((p = (char *) mg_malloc(len + 1)) != NULL) {
- mg_strlcpy(p, ptr, len + 1);
- }
-
- return p;
-}
-
-static char * mg_strdup(const char *str)
-{
- return mg_strndup(str, strlen(str));
-}
-
-static const char *mg_strcasestr(const char *big_str, const char *small_str)
-{
- int i, big_len = (int)strlen(big_str), small_len = (int)strlen(small_str);
-
- for (i = 0; i <= big_len - small_len; i++) {
- if (mg_strncasecmp(big_str + i, small_str, small_len) == 0) {
- return big_str + i;
- }
- }
-
- return NULL;
-}
-
-/* Like snprintf(), but never returns negative value, or a value
- that is larger than a supplied buffer.
- Thanks to Adam Zeldis to pointing snprintf()-caused vulnerability
- in his audit report. */
-static int mg_vsnprintf(struct mg_connection *conn, char *buf, size_t buflen,
- const char *fmt, va_list ap)
-{
- int n;
-
- if (buflen == 0)
- return 0;
-
- n = vsnprintf(buf, buflen, fmt, ap);
-
- if (n < 0) {
- mg_cry(conn, "vsnprintf error");
- n = 0;
- } else if (n >= (int) buflen) {
- mg_cry(conn, "truncating vsnprintf buffer: [%.*s]",
- n > 200 ? 200 : n, buf);
- n = (int) buflen - 1;
- }
- buf[n] = '\0';
-
- return n;
-}
-
-static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
- PRINTF_FORMAT_STRING(const char *fmt), ...)
-PRINTF_ARGS(4, 5);
-
-static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
- const char *fmt, ...)
-{
- va_list ap;
- int n;
-
- va_start(ap, fmt);
- n = mg_vsnprintf(conn, buf, buflen, fmt, ap);
- va_end(ap);
-
- return n;
-}
-
-static int get_option_index(const char *name)
-{
- int i;
-
- for (i = 0; config_options[i].name != NULL; i++) {
- if (strcmp(config_options[i].name, name) == 0) {
- return i;
- }
- }
- return -1;
-}
-
-const char *mg_get_option(const struct mg_context *ctx, const char *name)
-{
- int i;
- if ((i = get_option_index(name)) == -1) {
- return NULL;
- } else if (ctx->config[i] == NULL) {
- return "";
- } else {
- return ctx->config[i];
- }
-}
-
-struct mg_context *mg_get_context(struct mg_connection * conn)
-{
- return (conn == NULL) ? (struct mg_context *)NULL : (conn->ctx);
-}
-
-void *mg_get_user_data(struct mg_context *ctx)
-{
- return (ctx == NULL) ? NULL : ctx->user_data;
-}
-
-size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl)
-{
- size_t i;
- for (i = 0; i < size && i < (size_t)ctx->num_listening_sockets; i++)
- {
- ssl[i] = ctx->listening_sockets[i].is_ssl;
- ports[i] = ctx->listening_ports[i];
- }
- return i;
-}
-
-static void sockaddr_to_string(char *buf, size_t len,
- const union usa *usa)
-{
- buf[0] = '\0';
-#if defined(USE_IPV6)
- inet_ntop(usa->sa.sa_family, usa->sa.sa_family == AF_INET ?
- (void *) &usa->sin.sin_addr :
- (void *) &usa->sin6.sin6_addr, buf, len);
-#elif defined(_WIN32)
- /* Only Windows Vista (and newer) have inet_ntop() */
- mg_strlcpy(buf, inet_ntoa(usa->sin.sin_addr), len);
-#else
- inet_ntop(usa->sa.sa_family, (void *) &usa->sin.sin_addr, buf, len);
-#endif
-}
-
-/* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be included in all responses other than 100, 101, 5xx. */
-static void gmt_time_string(char *buf, size_t buf_len, time_t *t)
-{
- struct tm *tm;
-
- tm = gmtime(t);
- if (tm != NULL) {
- strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm);
- } else {
- mg_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
- buf[buf_len - 1] = '\0';
- }
-}
-
-/* Print error message to the opened error log stream. */
-void mg_cry(struct mg_connection *conn, const char *fmt, ...)
-{
- char buf[MG_BUF_LEN], src_addr[IP_ADDR_STR_LEN];
- va_list ap;
- FILE *fp;
- time_t timestamp;
-
- va_start(ap, fmt);
- IGNORE_UNUSED_RESULT(vsnprintf(buf, sizeof(buf), fmt, ap));
- va_end(ap);
-
- /* Do not lock when getting the callback value, here and below.
- I suppose this is fine, since function cannot disappear in the
- same way string option can. */
- if (conn->ctx->callbacks.log_message == NULL ||
- conn->ctx->callbacks.log_message(conn, buf) == 0) {
- fp = conn->ctx->config[ERROR_LOG_FILE] == NULL ? NULL :
- fopen(conn->ctx->config[ERROR_LOG_FILE], "a+");
-
- if (fp != NULL) {
- flockfile(fp);
- timestamp = time(NULL);
-
- sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
- fprintf(fp, "[%010lu] [error] [client %s] ", (unsigned long) timestamp,
- src_addr);
-
- if (conn->request_info.request_method != NULL) {
- fprintf(fp, "%s %s: ", conn->request_info.request_method,
- conn->request_info.uri);
- }
-
- fprintf(fp, "%s", buf);
- fputc('\n', fp);
- funlockfile(fp);
- fclose(fp);
- }
- }
-}
-
-/* Return fake connection structure. Used for logging, if connection
- is not applicable at the moment of logging. */
-static struct mg_connection *fc(struct mg_context *ctx)
-{
- static struct mg_connection fake_connection;
- fake_connection.ctx = ctx;
- return &fake_connection;
-}
-
-const char *mg_version(void)
-{
- return CIVETWEB_VERSION;
-}
-
-struct mg_request_info *mg_get_request_info(struct mg_connection *conn)
-{
- return &conn->request_info;
-}
-
-/* Skip the characters until one of the delimiters characters found.
- 0-terminate resulting word. Skip the delimiter and following whitespaces.
- Advance pointer to buffer to the next word. Return found 0-terminated word.
- Delimiters can be quoted with quotechar. */
-static char *skip_quoted(char **buf, const char *delimiters,
- const char *whitespace, char quotechar)
-{
- char *p, *begin_word, *end_word, *end_whitespace;
-
- begin_word = *buf;
- end_word = begin_word + strcspn(begin_word, delimiters);
-
- /* Check for quotechar */
- if (end_word > begin_word) {
- p = end_word - 1;
- while (*p == quotechar) {
- /* TODO (bel): it seems this code is never reached, so quotechar is actually
- not needed - check if this code may be droped */
-
- /* If there is anything beyond end_word, copy it */
- if (*end_word == '\0') {
- *p = '\0';
- break;
- } else {
- size_t end_off = strcspn(end_word + 1, delimiters);
- memmove (p, end_word, end_off + 1);
- p += end_off; /* p must correspond to end_word - 1 */
- end_word += end_off + 1;
- }
- }
- for (p++; p < end_word; p++) {
- *p = '\0';
- }
- }
-
- if (*end_word == '\0') {
- *buf = end_word;
- } else {
- end_whitespace = end_word + 1 + strspn(end_word + 1, whitespace);
-
- for (p = end_word; p < end_whitespace; p++) {
- *p = '\0';
- }
-
- *buf = end_whitespace;
- }
-
- return begin_word;
-}
-
-/* Simplified version of skip_quoted without quote char
- and whitespace == delimiters */
-static char *skip(char **buf, const char *delimiters)
-{
- return skip_quoted(buf, delimiters, delimiters, 0);
-}
-
-
-/* Return HTTP header value, or NULL if not found. */
-static const char *get_header(const struct mg_request_info *ri,
- const char *name)
-{
- int i;
-
- for (i = 0; i < ri->num_headers; i++)
- if (!mg_strcasecmp(name, ri->http_headers[i].name))
- return ri->http_headers[i].value;
-
- return NULL;
-}
-
-const char *mg_get_header(const struct mg_connection *conn, const char *name)
-{
- return get_header(&conn->request_info, name);
-}
-
-/* A helper function for traversing a comma separated list of values.
- It returns a list pointer shifted to the next value, or NULL if the end
- of the list found.
- Value is stored in val vector. If value has form "x=y", then eq_val
- vector is initialized to point to the "y" part, and val vector length
- is adjusted to point only to "x". */
-static const char *next_option(const char *list, struct vec *val,
- struct vec *eq_val)
-{
- if (list == NULL || *list == '\0') {
- /* End of the list */
- list = NULL;
- } else {
- val->ptr = list;
- if ((list = strchr(val->ptr, ',')) != NULL) {
- /* Comma found. Store length and shift the list ptr */
- val->len = list - val->ptr;
- list++;
- } else {
- /* This value is the last one */
- list = val->ptr + strlen(val->ptr);
- val->len = list - val->ptr;
- }
-
- if (eq_val != NULL) {
- /* Value has form "x=y", adjust pointers and lengths
- so that val points to "x", and eq_val points to "y". */
- eq_val->len = 0;
- eq_val->ptr = (const char *) memchr(val->ptr, '=', val->len);
- if (eq_val->ptr != NULL) {
- eq_val->ptr++; /* Skip over '=' character */
- eq_val->len = val->ptr + val->len - eq_val->ptr;
- val->len = (eq_val->ptr - val->ptr) - 1;
- }
- }
- }
-
- return list;
-}
-
-/* Perform case-insensitive match of string against pattern */
-static int match_prefix(const char *pattern, int pattern_len, const char *str)
-{
- const char *or_str;
- int i, j, len, res;
-
- if ((or_str = (const char *) memchr(pattern, '|', pattern_len)) != NULL) {
- res = match_prefix(pattern, (int)(or_str - pattern), str);
- return res > 0 ? res :
- match_prefix(or_str + 1, (int)((pattern + pattern_len) - (or_str + 1)), str);
- }
-
- i = j = 0;
- for (; i < pattern_len; i++, j++) {
- if (pattern[i] == '?' && str[j] != '\0') {
- continue;
- } else if (pattern[i] == '$') {
- return str[j] == '\0' ? j : -1;
- } else if (pattern[i] == '*') {
- i++;
- if (pattern[i] == '*') {
- i++;
- len = (int) strlen(str + j);
- } else {
- len = (int) strcspn(str + j, "/");
- }
- if (i == pattern_len) {
- return j + len;
- }
- do {
- res = match_prefix(pattern + i, pattern_len - i, str + j + len);
- } while (res == -1 && len-- > 0);
- return res == -1 ? -1 : j + res + len;
- } else if (lowercase(&pattern[i]) != lowercase(&str[j])) {
- return -1;
- }
- }
- return j;
-}
-
-/* HTTP 1.1 assumes keep alive if "Connection:" header is not set
- This function must tolerate situations when connection info is not
- set up, for example if request parsing failed. */
-static int should_keep_alive(const struct mg_connection *conn)
-{
- const char *http_version = conn->request_info.http_version;
- const char *header = mg_get_header(conn, "Connection");
- if (conn->must_close ||
- conn->status_code == 401 ||
- mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 ||
- (header != NULL && mg_strcasecmp(header, "keep-alive") != 0) ||
- (header == NULL && http_version && 0!=strcmp(http_version, "1.1"))) {
- return 0;
- }
- return 1;
-}
-
-static int should_decode_url(const struct mg_connection *conn)
-{
- return (mg_strcasecmp(conn->ctx->config[DECODE_URL], "yes") == 0);
-}
-
-static const char *suggest_connection_header(const struct mg_connection *conn)
-{
- return should_keep_alive(conn) ? "keep-alive" : "close";
-}
-
-static void handle_file_based_request(struct mg_connection *conn, const char *path, struct file *filep);
-static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep);
-
-static const char *mg_get_response_code_text(int response_code, struct mg_connection *conn)
-{
- switch (response_code)
- {
- /* RFC2616 Section 10.1 - Informational 1xx */
- case 100: return "Continue"; /* RFC2616 Section 10.1.1 */
- case 101: return "Switching Protocols"; /* RFC2616 Section 10.1.2 */
- case 102: return "Processing"; /* RFC2518 Section 10.1 */
-
- /* RFC2616 Section 10.2 - Successful 2xx */
- case 200: return "OK"; /* RFC2616 Section 10.2.1 */
- case 201: return "Created"; /* RFC2616 Section 10.2.2 */
- case 202: return "Accepted"; /* RFC2616 Section 10.2.3 */
- case 203: return "Non-Authoritative Information"; /* RFC2616 Section 10.2.4 */
- case 204: return "No Content"; /* RFC2616 Section 10.2.5 */
- case 205: return "Reset Content"; /* RFC2616 Section 10.2.6 */
- case 206: return "Partial Content"; /* RFC2616 Section 10.2.7 */
- case 207: return "Multi-Status"; /* RFC2518 Section 10.2, RFC4918 Section 11.1 */
-
- /* RFC2616 Section 10.3 - Redirection 3xx */
- case 300: return "Multiple Choices"; /* RFC2616 Section 10.3.1 */
- case 301: return "Moved Permanently"; /* RFC2616 Section 10.3.2 */
- case 302: return "Found"; /* RFC2616 Section 10.3.3 */
- case 303: return "See Other"; /* RFC2616 Section 10.3.4 */
- case 304: return "Not Modified"; /* RFC2616 Section 10.3.5 */
- case 305: return "Use Proxy"; /* RFC2616 Section 10.3.6 */
- case 307: return "Temporary Redirect"; /* RFC2616 Section 10.3.8 */
-
- /* RFC2616 Section 10.4 - Client Error 4xx */
- case 400: return "Bad Request"; /* RFC2616 Section 10.4.1 */
- case 401: return "Unauthorized"; /* RFC2616 Section 10.4.2 */
- case 402: return "Payment Required"; /* RFC2616 Section 10.4.3 */
- case 403: return "Forbidden"; /* RFC2616 Section 10.4.4 */
- case 404: return "Not Found"; /* RFC2616 Section 10.4.5 */
- case 405: return "Method Not Allowed"; /* RFC2616 Section 10.4.6 */
- case 406: return "Not Acceptable"; /* RFC2616 Section 10.4.7 */
- case 407: return "Proxy Authentication Required"; /* RFC2616 Section 10.4.8 */
- case 408: return "Request Time-out"; /* RFC2616 Section 10.4.9 */
- case 409: return "Conflict"; /* RFC2616 Section 10.4.10 */
- case 410: return "Gone"; /* RFC2616 Section 10.4.11 */
- case 411: return "Length Required"; /* RFC2616 Section 10.4.12 */
- case 412: return "Precondition Failed"; /* RFC2616 Section 10.4.13 */
- case 413: return "Request Entity Too Large"; /* RFC2616 Section 10.4.14 */
- case 414: return "Request-URI Too Large"; /* RFC2616 Section 10.4.15 */
- case 415: return "Unsupported Media Type"; /* RFC2616 Section 10.4.16 */
- case 416: return "Requested range not satisfiable"; /* RFC2616 Section 10.4.17 */
- case 417: return "Expectation Failed"; /* RFC2616 Section 10.4.18 */
- case 422: return "Unproccessable entity"; /* RFC2518 Section 10.3, RFC4918 Section 11.2 */
- case 423: return "Locked"; /* RFC2518 Section 10.4, RFC4918 Section 11.3 */
- case 424: return "Failed Dependency"; /* RFC2518 Section 10.5, RFC4918 Section 11.4 */
- case 428: return "Precondition Required"; /* RFC 6585, Section 3 */
- case 429: return "Too Many Requests"; /* RFC 6585, Section 4 */
- case 431: return "Request Header Fields Too Large"; /* RFC 6585, Section 5 */
-
- /* RFC2616 Section 10.5 - Server Error 5xx */
- case 500: return "Internal Server Error"; /* RFC2616 Section 10.5.1 */
- case 501: return "Not Implemented"; /* RFC2616 Section 10.5.2 */
- case 502: return "Bad Gateway"; /* RFC2616 Section 10.5.3 */
- case 503: return "Service Unavailable"; /* RFC2616 Section 10.5.4 */
- case 504: return "Gateway Time-out"; /* RFC2616 Section 10.5.5 */
- case 505: return "HTTP Version not supported"; /* RFC2616 Section 10.5.6 */
- case 507: return "Insufficient Storage"; /* RFC2518 Section 10.6, , RFC4918 Section 11.5 */
- case 511: return "Network Authentication Required"; /* RFC 6585, Section 6 */
-
- /* Other RFCs */
- case 426: return "Upgrade Required"; /* RFC 2817 */
-
- /* Return codes from non normative RFCs: */
- /* Informative and experimental RFCs, "de facto" standards due to common use, ... */
- case 208: return "Already Reported"; /* RFC5842 Section 7.1 */
- case 226: return "IM used"; /* RFC3229 Section 10.4.1 */
- case 308: return "Permanent Redirect"; /* RFC7238 Section 3 */
- case 418: return "I am a teapot"; /* RFC2324 Section 2.3.2 */
- case 419: return "Authentication Timeout"; /* common use */
- case 451: return "Unavailable For Legal Reasons"; /* draft-tbray-http-legally-restricted-status-05, Section 3 */
- case 506: return "Variant Also Negotiates"; /* RFC 2295, Section 8.1 */
- case 508: return "Loop Detected"; /* RFC5842 Section 7.1 */
- case 510: return "Not Extended"; /* RFC 2774, Section 7 */
-
- default:
- /* This error code is unknown. This should not happen. */
- if (conn) {
- mg_cry(conn, "Unknown HTTP response code: %u", response_code);
- }
-
- /* Return at least a category according to RFC 2616 Section 10. */
- if (response_code>=100 && response_code<200) {
- /* Unknown informational status code */
- return "Information";
- }
- if (response_code>=200 && response_code<300) {
- /* Unknown success code */
- return "Success";
- }
- if (response_code>=300 && response_code<400) {
- /* Unknown redirection code */
- return "Redirection";
- }
- if (response_code>=400 && response_code<500) {
- /* Unknown request error code */
- return "Client Error";
- }
- if (response_code>=500 && response_code<600) {
- /* Unknown server error code */
- return "Server Error";
- }
-
- /* Response code not even within reasonable range */
- return "";
- }
-}
-
-
-static void send_http_error(struct mg_connection *, int, const char *,
- PRINTF_FORMAT_STRING(const char *fmt), ...)
-PRINTF_ARGS(4, 5);
-
-
-static void send_http_error(struct mg_connection *conn, int status,
- const char *reason, const char *fmt, ...)
-{
- char buf[MG_BUF_LEN];
- va_list ap;
- int len = 0, i, page_handler_found, scope;
- char date[64];
- time_t curtime = time(NULL);
- const char *error_handler = NULL;
- struct file error_page_file = STRUCT_FILE_INITIALIZER;
- const char *error_page_file_ext, *tstr;
-
- if (!reason) {
- reason = mg_get_response_code_text(status, conn);
- }
-
- conn->status_code = status;
- if (conn->in_error_handler ||
- conn->ctx->callbacks.http_error == NULL ||
- conn->ctx->callbacks.http_error(conn, status)) {
-
- if (!conn->in_error_handler) {
- /* Send user defined error pages, if defined */
- error_handler = conn->ctx->config[ERROR_PAGES];
- error_page_file_ext = conn->ctx->config[INDEX_FILES];
- page_handler_found = 0;
- if (error_handler != NULL) {
- for (scope=1; (scope<=3) && !page_handler_found; scope++) {
- switch (scope) {
- case 1:
- len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%03u.", error_handler, status);
- break;
- case 2:
- len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%01uxx.", error_handler, status/100);
- break;
- default:
- len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror.", error_handler);
- break;
- }
- tstr = strchr(error_page_file_ext, '.');
- while (tstr) {
- for (i=1; i<32 && tstr[i]!=0 && tstr[i]!=','; i++) buf[len+i-1]=tstr[i];
- buf[len+i-1]=0;
- if (mg_stat(conn, buf, &error_page_file)) {
- page_handler_found = 1;
- break;
- }
- tstr = strchr(tstr+i, '.');
- }
- }
- }
-
- if (page_handler_found) {
- conn->in_error_handler = 1;
- handle_file_based_request(conn, buf, &error_page_file);
- conn->in_error_handler = 0;
- return;
- }
- }
-
- buf[0] = '\0';
- gmt_time_string(date, sizeof(date), &curtime);
-
- /* Errors 1xx, 204 and 304 MUST NOT send a body */
- if (status > 199 && status != 204 && status != 304) {
- len = mg_snprintf(conn, buf, sizeof(buf)-1, "Error %d: %s", status, reason);
- buf[len] = '\n';
- len++;
- buf[len] = 0;
-
- va_start(ap, fmt);
- len += mg_vsnprintf(conn, buf + len, sizeof(buf) - len, fmt, ap);
- va_end(ap);
- }
- DEBUG_TRACE("[%s]", buf);
-
- mg_printf(conn, "HTTP/1.1 %d %s\r\n"
- "Content-Length: %d\r\n"
- "Date: %s\r\n"
- "Connection: %s\r\n\r\n",
- status, reason, len, date,
- suggest_connection_header(conn));
- conn->num_bytes_sent += mg_printf(conn, "%s", buf);
- }
-}
-
-#if defined(_WIN32) && !defined(__SYMBIAN32__)
-static int pthread_mutex_init(pthread_mutex_t *mutex, void *unused)
-{
- (void) unused;
- *mutex = CreateMutex(NULL, FALSE, NULL);
- return *mutex == NULL ? -1 : 0;
-}
-
-static int pthread_mutex_destroy(pthread_mutex_t *mutex)
-{
- return CloseHandle(*mutex) == 0 ? -1 : 0;
-}
-
-static int pthread_mutex_lock(pthread_mutex_t *mutex)
-{
- return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
-}
-
-static int pthread_mutex_trylock(pthread_mutex_t *mutex)
-{
- switch (WaitForSingleObject(*mutex, 0)) {
- case WAIT_OBJECT_0:
- return 0;
- case WAIT_TIMEOUT:
- return -2; /* EBUSY */
- }
- return -1;
-}
-
-static int pthread_mutex_unlock(pthread_mutex_t *mutex)
-{
- return ReleaseMutex(*mutex) == 0 ? -1 : 0;
-}
-
-#ifndef WIN_PTHREADS_TIME_H
-static int clock_gettime(clockid_t clk_id, struct timespec *tp)
-{
- FILETIME ft;
- ULARGE_INTEGER li;
- BOOL ok = FALSE;
- double d;
- static double perfcnt_per_sec = 0.0;
-
- if (tp) {
- if (clk_id == CLOCK_REALTIME) {
- GetSystemTimeAsFileTime(&ft);
- li.LowPart = ft.dwLowDateTime;
- li.HighPart = ft.dwHighDateTime;
- li.QuadPart -= 116444736000000000; /* 1.1.1970 in filedate */
- tp->tv_sec = (time_t)(li.QuadPart / 10000000);
- tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
- ok = TRUE;
- } else if (clk_id == CLOCK_MONOTONIC) {
- if (perfcnt_per_sec == 0.0) {
- QueryPerformanceFrequency((LARGE_INTEGER *) &li);
- perfcnt_per_sec = 1.0 / li.QuadPart;
- }
- if (perfcnt_per_sec != 0.0) {
- QueryPerformanceCounter((LARGE_INTEGER *) &li);
- d = li.QuadPart * perfcnt_per_sec;
- tp->tv_sec = (time_t)d;
- d -= tp->tv_sec;
- tp->tv_nsec = (long)(d*1.0E9);
- ok = TRUE;
- }
- }
- }
-
- return ok ? 0 : -1;
-}
-#endif
-
-static int pthread_cond_init(pthread_cond_t *cv, const void *unused)
-{
- (void) unused;
- InitializeCriticalSection(&cv->threadIdSec);
- cv->waitingthreadcount = 0;
- cv->waitingthreadhdls = (pthread_t *) mg_calloc(MAX_WORKER_THREADS, sizeof(pthread_t));
- return (cv->waitingthreadhdls!=NULL) ? 0 : -1;
-}
-
-static int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mutex, const struct timespec * abstime)
-{
- struct mg_workerTLS * tls = (struct mg_workerTLS *)TlsGetValue(sTlsKey);
- int ok;
- struct timespec tsnow;
- int64_t nsnow, nswaitabs, nswaitrel;
- DWORD mswaitrel;
-
- EnterCriticalSection(&cv->threadIdSec);
- assert(cv->waitingthreadcount < MAX_WORKER_THREADS);
- cv->waitingthreadhdls[cv->waitingthreadcount] = tls->pthread_cond_helper_mutex;
- cv->waitingthreadcount++;
- LeaveCriticalSection(&cv->threadIdSec);
-
- if (abstime) {
- clock_gettime(CLOCK_REALTIME, &tsnow);
- nsnow = (((uint64_t)tsnow.tv_sec)*1000000000) + tsnow.tv_nsec;
- nswaitabs = (((uint64_t)abstime->tv_sec)*1000000000) + abstime->tv_nsec;
- nswaitrel = nswaitabs - nsnow;
- if (nswaitrel<0) nswaitrel=0;
- mswaitrel = (DWORD)(nswaitrel / 1000000);
- } else {
- mswaitrel = INFINITE;
- }
-
- pthread_mutex_unlock(mutex);
- ok = (WAIT_OBJECT_0 == WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel));
- pthread_mutex_lock(mutex);
-
- return ok ? 0 : -1;
-}
-
-static int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex)
-{
- return pthread_cond_timedwait(cv, mutex, NULL);
-}
-
-static int pthread_cond_signal(pthread_cond_t *cv)
-{
- int i;
- HANDLE wkup = NULL;
- BOOL ok = FALSE;
-
- EnterCriticalSection(&cv->threadIdSec);
- if (cv->waitingthreadcount) {
- wkup = cv->waitingthreadhdls[0];
- ok = SetEvent(wkup);
-
- for (i=1; i<cv->waitingthreadcount; i++) {
- cv->waitingthreadhdls[i-1] = cv->waitingthreadhdls[i];
- }
- cv->waitingthreadcount--;
-
- assert(ok);
- }
- LeaveCriticalSection(&cv->threadIdSec);
-
- return ok ? 0 : 1;
-}
-
-static int pthread_cond_broadcast(pthread_cond_t *cv)
-{
- EnterCriticalSection(&cv->threadIdSec);
- while (cv->waitingthreadcount) {
- pthread_cond_signal(cv);
- }
- LeaveCriticalSection(&cv->threadIdSec);
-
- return 0;
-}
-
-static int pthread_cond_destroy(pthread_cond_t *cv)
-{
- EnterCriticalSection(&cv->threadIdSec);
- assert(cv->waitingthreadcount==0);
- mg_free(cv->waitingthreadhdls);
- cv->waitingthreadhdls = 0;
- LeaveCriticalSection(&cv->threadIdSec);
- DeleteCriticalSection(&cv->threadIdSec);
-
- return 0;
-}
-
-/* For Windows, change all slashes to backslashes in path names. */
-static void change_slashes_to_backslashes(char *path)
-{
- int i;
-
- for (i = 0; path[i] != '\0'; i++) {
- if (path[i] == '/')
- path[i] = '\\';
- /* i > 0 check is to preserve UNC paths, like \\server\file.txt */
- if (path[i] == '\\' && i > 0)
- while (path[i + 1] == '\\' || path[i + 1] == '/')
- (void) memmove(path + i + 1,
- path + i + 2, strlen(path + i + 1));
- }
-}
-
-/* Encode 'path' which is assumed UTF-8 string, into UNICODE string.
- wbuf and wbuf_len is a target buffer and its length. */
-static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len)
-{
- char buf[PATH_MAX], buf2[PATH_MAX];
-
- mg_strlcpy(buf, path, sizeof(buf));
- change_slashes_to_backslashes(buf);
-
- /* Convert to Unicode and back. If doubly-converted string does not
- match the original, something is fishy, reject. */
- memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
- WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
- NULL, NULL);
- if (strcmp(buf, buf2) != 0) {
- wbuf[0] = L'\0';
- }
-}
-
-#if defined(_WIN32_WCE)
-static time_t time(time_t *ptime)
-{
- time_t t;
- SYSTEMTIME st;
- FILETIME ft;
-
- GetSystemTime(&st);
- SystemTimeToFileTime(&st, &ft);
- t = SYS2UNIX_TIME(ft.dwLowDateTime, ft.dwHighDateTime);
-
- if (ptime != NULL) {
- *ptime = t;
- }
-
- return t;
-}
-
-static struct tm *localtime(const time_t *ptime, struct tm *ptm)
-{
- int64_t t = ((int64_t) *ptime) * RATE_DIFF + EPOCH_DIFF;
- FILETIME ft, lft;
- SYSTEMTIME st;
- TIME_ZONE_INFORMATION tzinfo;
-
- if (ptm == NULL) {
- return NULL;
- }
-
- * (int64_t *) &ft = t;
- FileTimeToLocalFileTime(&ft, &lft);
- FileTimeToSystemTime(&lft, &st);
- ptm->tm_year = st.wYear - 1900;
- ptm->tm_mon = st.wMonth - 1;
- ptm->tm_wday = st.wDayOfWeek;
- ptm->tm_mday = st.wDay;
- ptm->tm_hour = st.wHour;
- ptm->tm_min = st.wMinute;
- ptm->tm_sec = st.wSecond;
- ptm->tm_yday = 0; /* hope nobody uses this */
- ptm->tm_isdst =
- GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT ? 1 : 0;
-
- return ptm;
-}
-
-static struct tm *gmtime(const time_t *ptime, struct tm *ptm)
-{
- /* FIXME(lsm): fix this. */
- return localtime(ptime, ptm);
-}
-
-static size_t strftime(char *dst, size_t dst_size, const char *fmt,
- const struct tm *tm)
-{
- (void) snprintf(dst, dst_size, "implement strftime() for WinCE");
- return 0;
-}
-#endif
-
-/* Windows happily opens files with some garbage at the end of file name.
- For example, fopen("a.cgi ", "r") on Windows successfully opens
- "a.cgi", despite one would expect an error back.
- This function returns non-0 if path ends with some garbage. */
-static int path_cannot_disclose_cgi(const char *path)
-{
- static const char *allowed_last_characters = "_-";
- int last = path[strlen(path) - 1];
- return isalnum(last) || strchr(allowed_last_characters, last) != NULL;
-}
-
-static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep)
-{
- wchar_t wbuf[PATH_MAX];
- WIN32_FILE_ATTRIBUTE_DATA info;
-
- if (!is_file_in_memory(conn, path, filep)) {
- to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
- if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) {
- filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
- filep->modification_time = SYS2UNIX_TIME(
- info.ftLastWriteTime.dwLowDateTime,
- info.ftLastWriteTime.dwHighDateTime);
- filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
- /* If file name is fishy, reset the file structure and return
- error.
- Note it is important to reset, not just return the error, cause
- functions like is_file_opened() check the struct. */
- if (!filep->is_directory && !path_cannot_disclose_cgi(path)) {
- memset(filep, 0, sizeof(*filep));
- }
- }
- }
-
- return filep->membuf != NULL || filep->modification_time != 0;
-}
-
-static int mg_remove(const char *path)
-{
- wchar_t wbuf[PATH_MAX];
- to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
- return DeleteFileW(wbuf) ? 0 : -1;
-}
-
-static int mg_mkdir(const char *path, int mode)
-{
- char buf[PATH_MAX];
- wchar_t wbuf[PATH_MAX];
-
- (void) mode;
- mg_strlcpy(buf, path, sizeof(buf));
- change_slashes_to_backslashes(buf);
-
- (void) MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, ARRAY_SIZE(wbuf));
-
- return CreateDirectoryW(wbuf, NULL) ? 0 : -1;
-}
-
-/* Implementation of POSIX opendir/closedir/readdir for Windows. */
-static DIR * opendir(const char *name)
-{
- DIR *dir = NULL;
- wchar_t wpath[PATH_MAX];
- DWORD attrs;
-
- if (name == NULL) {
- SetLastError(ERROR_BAD_ARGUMENTS);
- } else if ((dir = (DIR *) mg_malloc(sizeof(*dir))) == NULL) {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- } else {
- to_unicode(name, wpath, ARRAY_SIZE(wpath));
- attrs = GetFileAttributesW(wpath);
- if (attrs != 0xFFFFFFFF &&
- ((attrs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)) {
- (void) wcscat(wpath, L"\\*");
- dir->handle = FindFirstFileW(wpath, &dir->info);
- dir->result.d_name[0] = '\0';
- } else {
- mg_free(dir);
- dir = NULL;
- }
- }
-
- return dir;
-}
-
-static int closedir(DIR *dir)
-{
- int result = 0;
-
- if (dir != NULL) {
- if (dir->handle != INVALID_HANDLE_VALUE)
- result = FindClose(dir->handle) ? 0 : -1;
-
- mg_free(dir);
- } else {
- result = -1;
- SetLastError(ERROR_BAD_ARGUMENTS);
- }
-
- return result;
-}
-
-static struct dirent *readdir(DIR *dir)
-{
- struct dirent *result = 0;
-
- if (dir) {
- if (dir->handle != INVALID_HANDLE_VALUE) {
- result = &dir->result;
- (void) WideCharToMultiByte(CP_UTF8, 0,
- dir->info.cFileName, -1, result->d_name,
- sizeof(result->d_name), NULL, NULL);
-
- if (!FindNextFileW(dir->handle, &dir->info)) {
- (void) FindClose(dir->handle);
- dir->handle = INVALID_HANDLE_VALUE;
- }
-
- } else {
- SetLastError(ERROR_FILE_NOT_FOUND);
- }
- } else {
- SetLastError(ERROR_BAD_ARGUMENTS);
- }
-
- return result;
-}
-
-#ifndef HAVE_POLL
-static int poll(struct pollfd *pfd, int n, int milliseconds)
-{
- struct timeval tv;
- fd_set set;
- int i, result;
- SOCKET maxfd = 0;
-
- tv.tv_sec = milliseconds / 1000;
- tv.tv_usec = (milliseconds % 1000) * 1000;
- FD_ZERO(&set);
-
- for (i = 0; i < n; i++) {
- FD_SET((SOCKET) pfd[i].fd, &set);
- pfd[i].revents = 0;
-
- if (pfd[i].fd > maxfd) {
- maxfd = pfd[i].fd;
- }
- }
-
- if ((result = select((int)maxfd + 1, &set, NULL, NULL, &tv)) > 0) {
- for (i = 0; i < n; i++) {
- if (FD_ISSET(pfd[i].fd, &set)) {
- pfd[i].revents = POLLIN;
- }
- }
- }
-
- return result;
-}
-#endif /* HAVE_POLL */
-
-static void set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */)
-{
- (void) conn; /* Unused. */
- (void) SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0);
-}
-
-int mg_start_thread(mg_thread_func_t f, void *p)
-{
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
- /* Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 */
- return ((_beginthread((void (__cdecl *)(void *)) f, USE_STACK_SIZE, p) == ((uintptr_t)(-1L))) ? -1 : 0);
-#else
- return ((_beginthread((void (__cdecl *)(void *)) f, 0, p) == ((uintptr_t)(-1L))) ? -1 : 0);
-#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
-}
-
-/* Start a thread storing the thread context. */
-
-static int mg_start_thread_with_id(unsigned (__stdcall *f)(void *), void *p,
- pthread_t *threadidptr)
-{
- uintptr_t uip;
- HANDLE threadhandle;
- int result = -1;
-
- uip = _beginthreadex(NULL, 0, (unsigned (__stdcall *)(void *)) f, p, 0,
- NULL);
- threadhandle = (HANDLE) uip;
- if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) {
- *threadidptr = threadhandle;
- result = 0;
- }
-
- return result;
-}
-
-/* Wait for a thread to finish. */
-
-static int mg_join_thread(pthread_t threadid)
-{
- int result;
- DWORD dwevent;
-
- result = -1;
- dwevent = WaitForSingleObject(threadid, INFINITE);
- if (dwevent == WAIT_FAILED) {
- int err;
-
- err = GetLastError();
- DEBUG_TRACE("WaitForSingleObject() failed, error %d", err);
- } else {
- if (dwevent == WAIT_OBJECT_0) {
- CloseHandle(threadid);
- result = 0;
- }
- }
-
- return result;
-}
-
-static HANDLE dlopen(const char *dll_name, int flags)
-{
- wchar_t wbuf[PATH_MAX];
- (void) flags;
- to_unicode(dll_name, wbuf, ARRAY_SIZE(wbuf));
- return LoadLibraryW(wbuf);
-}
-
-static int dlclose(void *handle)
-{
- int result;
-
- if (FreeLibrary((HMODULE) handle) != 0) {
- result = 0;
- } else {
- result = -1;
- }
-
- return result;
-}
-
-#if !defined(NO_CGI)
-#define SIGKILL 0
-static int kill(pid_t pid, int sig_num)
-{
- (void) TerminateProcess(pid, sig_num);
- (void) CloseHandle(pid);
- return 0;
-}
-
-static void trim_trailing_whitespaces(char *s)
-{
- char *e = s + strlen(s) - 1;
- while (e > s && isspace(* (unsigned char *) e)) {
- *e-- = '\0';
- }
-}
-
-static pid_t spawn_process(struct mg_connection *conn, const char *prog,
- char *envblk, char *envp[], int fdin,
- int fdout, const char *dir)
-{
- HANDLE me;
- char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX],
- cmdline[PATH_MAX], buf[PATH_MAX];
- struct file file = STRUCT_FILE_INITIALIZER;
- STARTUPINFOA si;
- PROCESS_INFORMATION pi = { 0 };
-
- (void) envp;
-
- memset(&si, 0, sizeof(si));
- si.cb = sizeof(si);
-
- /* TODO(lsm): redirect CGI errors to the error log file */
- si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE;
-
- me = GetCurrentProcess();
- DuplicateHandle(me, (HANDLE) _get_osfhandle(fdin), me,
- &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS);
- DuplicateHandle(me, (HANDLE) _get_osfhandle(fdout), me,
- &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
-
- /* If CGI file is a script, try to read the interpreter line */
- interp = conn->ctx->config[CGI_INTERPRETER];
- if (interp == NULL) {
- buf[0] = buf[1] = '\0';
-
- /* Read the first line of the script into the buffer */
- snprintf(cmdline, sizeof(cmdline), "%s%c%s", dir, '/', prog);
- if (mg_fopen(conn, cmdline, "r", &file)) {
- p = (char *) file.membuf;
- mg_fgets(buf, sizeof(buf), &file, &p);
- mg_fclose(&file);
- buf[sizeof(buf) - 1] = '\0';
- }
-
- if (buf[0] == '#' && buf[1] == '!') {
- trim_trailing_whitespaces(buf + 2);
- } else {
- buf[2] = '\0';
- }
- interp = buf + 2;
- }
-
- if (interp[0] != '\0') {
- GetFullPathNameA(interp, sizeof(full_interp), full_interp, NULL);
- interp = full_interp;
- }
- GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL);
-
- mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%s\"%s\\%s\"",
- interp, interp[0] == '\0' ? "" : " ", full_dir, prog);
-
- DEBUG_TRACE("Running [%s]", cmdline);
- if (CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
- CREATE_NEW_PROCESS_GROUP, envblk, NULL, &si, &pi) == 0) {
- mg_cry(conn, "%s: CreateProcess(%s): %ld",
- __func__, cmdline, ERRNO);
- pi.hProcess = (pid_t) -1;
- }
-
- (void) CloseHandle(si.hStdOutput);
- (void) CloseHandle(si.hStdInput);
- if (pi.hThread != NULL)
- (void) CloseHandle(pi.hThread);
-
- return (pid_t) pi.hProcess;
-}
-#endif /* !NO_CGI */
-
-static int set_non_blocking_mode(SOCKET sock)
-{
- unsigned long on = 1;
- return ioctlsocket(sock, FIONBIO, &on);
-}
-
-#else
-static int mg_stat(struct mg_connection *conn, const char *path,
- struct file *filep)
-{
- struct stat st;
-
- if (!is_file_in_memory(conn, path, filep) && !stat(path, &st)) {
- filep->size = st.st_size;
- filep->modification_time = st.st_mtime;
- filep->is_directory = S_ISDIR(st.st_mode);
- } else {
- filep->modification_time = (time_t) 0;
- }
-
- return filep->membuf != NULL || filep->modification_time != (time_t) 0;
-}
-
-static void set_close_on_exec(int fd, struct mg_connection *conn /* may be null */)
-{
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
- if (conn) {
- mg_cry(conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, strerror(ERRNO));
- }
- }
-}
-
-int mg_start_thread(mg_thread_func_t func, void *param)
-{
- pthread_t thread_id;
- pthread_attr_t attr;
- int result;
-
- (void) pthread_attr_init(&attr);
- (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
- /* Compile-time option to control stack size,
- e.g. -DUSE_STACK_SIZE=16384 */
- (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
-#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
-
- result = pthread_create(&thread_id, &attr, func, param);
- pthread_attr_destroy(&attr);
-
- return result;
-}
-
-/* Start a thread storing the thread context. */
-
-static int mg_start_thread_with_id(mg_thread_func_t func, void *param, pthread_t *threadidptr)
-{
- pthread_t thread_id;
- pthread_attr_t attr;
- int result;
-
- (void) pthread_attr_init(&attr);
-
-#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
- /* Compile-time option to control stack size,
- e.g. -DUSE_STACK_SIZE=16384 */
- (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
-#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */
-
- result = pthread_create(&thread_id, &attr, func, param);
- pthread_attr_destroy(&attr);
- if ((result == 0) && (threadidptr != NULL)) {
- *threadidptr = thread_id;
- }
- return result;
-}
-
-/* Wait for a thread to finish. */
-
-static int mg_join_thread(pthread_t threadid)
-{
- int result;
-
- result = pthread_join(threadid, NULL);
- return result;
-}
-
-#ifndef NO_CGI
-static pid_t spawn_process(struct mg_connection *conn, const char *prog,
- char *envblk, char *envp[], int fdin,
- int fdout, const char *dir)
-{
- pid_t pid;
- const char *interp;
-
- (void) envblk;
-
- if ((pid = fork()) == -1) {
- /* Parent */
- send_http_error(conn, 500, NULL,
- "Error: Creating CGI process\nfork(): %s", strerror(ERRNO));
- } else if (pid == 0) {
- /* Child */
- if (chdir(dir) != 0) {
- mg_cry(conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO));
- } else if (dup2(fdin, 0) == -1) {
- mg_cry(conn, "%s: dup2(%d, 0): %s", __func__, fdin, strerror(ERRNO));
- } else if (dup2(fdout, 1) == -1) {
- mg_cry(conn, "%s: dup2(%d, 1): %s", __func__, fdout, strerror(ERRNO));
- } else {
- /* Not redirecting stderr to stdout, to avoid output being littered
- with the error messages. */
- (void) close(fdin);
- (void) close(fdout);
-
- /* After exec, all signal handlers are restored to their default
- values, with one exception of SIGCHLD. According to
- POSIX.1-2001 and Linux's implementation, SIGCHLD's handler will
- leave unchanged after exec if it was set to be ignored. Restore
- it to default action. */
- signal(SIGCHLD, SIG_DFL);
-
- interp = conn->ctx->config[CGI_INTERPRETER];
- if (interp == NULL) {
- (void) execle(prog, prog, NULL, envp);
- mg_cry(conn, "%s: execle(%s): %s", __func__, prog, strerror(ERRNO));
- } else {
- (void) execle(interp, interp, prog, NULL, envp);
- mg_cry(conn, "%s: execle(%s %s): %s", __func__, interp, prog,
- strerror(ERRNO));
- }
- }
- exit(EXIT_FAILURE);
- }
-
- return pid;
-}
-#endif /* !NO_CGI */
-
-static int set_non_blocking_mode(SOCKET sock)
-{
- int flags;
-
- flags = fcntl(sock, F_GETFL, 0);
- (void) fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-
- return 0;
-}
-#endif /* _WIN32 */
-
-/* Write data to the IO channel - opened file descriptor, socket or SSL
- descriptor. Return number of bytes written. */
-static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
-{
- int64_t sent;
- int n, k;
-
- (void) ssl; /* Get rid of warning */
- sent = 0;
- while (sent < len) {
-
- /* How many bytes we send in this iteration */
- k = len - sent > INT_MAX ? INT_MAX : (int) (len - sent);
-
-#ifndef NO_SSL
- if (ssl != NULL) {
- n = SSL_write(ssl, buf + sent, k);
- } else
-#endif
- if (fp != NULL) {
- n = (int) fwrite(buf + sent, 1, (size_t) k, fp);
- if (ferror(fp))
- n = -1;
- } else {
- n = send(sock, buf + sent, (size_t) k, MSG_NOSIGNAL);
- }
-
- if (n <= 0)
- break;
-
- sent += n;
- }
-
- return sent;
-}
-
-/* Read from IO channel - opened file descriptor, socket, or SSL descriptor.
- Return negative value on error, or number of bytes read on success. */
-static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len)
-{
- int nread;
-
- if (fp != NULL) {
- /* Use read() instead of fread(), because if we're reading from the
- CGI pipe, fread() may block until IO buffer is filled up. We cannot
- afford to block and must pass all read bytes immediately to the
- client. */
- nread = read(fileno(fp), buf, (size_t) len);
-#ifndef NO_SSL
- } else if (conn->ssl != NULL) {
- nread = SSL_read(conn->ssl, buf, len);
-#endif
- } else {
- nread = recv(conn->client.sock, buf, (size_t) len, 0);
- }
-
- return conn->ctx->stop_flag ? -1 : nread;
-}
-
-static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
-{
- int n, nread = 0;
-
- while (len > 0 && conn->ctx->stop_flag == 0) {
- n = pull(fp, conn, buf + nread, len);
- if (n < 0) {
- nread = n; /* Propagate the error */
- break;
- } else if (n == 0) {
- break; /* No more data to read */
- } else {
- conn->consumed_content += n;
- nread += n;
- len -= n;
- }
- }
-
- return nread;
-}
-
-int mg_read(struct mg_connection *conn, void *buf, size_t len)
-{
- int64_t n, buffered_len, nread;
- int64_t len64 = (int64_t)(len > INT_MAX ? INT_MAX : len); /* since the return value is int, we may not read more bytes */
- const char *body;
-
- /* If Content-Length is not set for a PUT or POST request, read until socket is closed */
- if (conn->consumed_content == 0 && conn->content_len == -1) {
- conn->content_len = INT64_MAX;
- conn->must_close = 1;
- }
-
- nread = 0;
- if (conn->consumed_content < conn->content_len) {
- /* Adjust number of bytes to read. */
- int64_t left_to_read = conn->content_len - conn->consumed_content;
- if (left_to_read < len64) {
- /* Do not reade more than the total content length of the request. */
- len64 = left_to_read;
- }
-
- /* Return buffered data */
- buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len - conn->consumed_content;
- if (buffered_len > 0) {
- if (len64 < buffered_len) {
- buffered_len = len64;
- }
- body = conn->buf + conn->request_len + conn->consumed_content;
- memcpy(buf, body, (size_t) buffered_len);
- len64 -= buffered_len;
- conn->consumed_content += buffered_len;
- nread += buffered_len;
- buf = (char *) buf + buffered_len;
- }
-
- /* We have returned all buffered data. Read new data from the remote
- socket. */
- if ((n = pull_all(NULL, conn, (char *) buf, (int)len64)) >= 0) {
- nread += n;
- } else {
- nread = (nread > 0 ? nread : n);
- }
- }
- return (int)nread;
-}
-
-int mg_write(struct mg_connection *conn, const void *buf, size_t len)
-{
- time_t now;
- int64_t n, total, allowed;
-
- if (conn->throttle > 0) {
- if ((now = time(NULL)) != conn->last_throttle_time) {
- conn->last_throttle_time = now;
- conn->last_throttle_bytes = 0;
- }
- allowed = conn->throttle - conn->last_throttle_bytes;
- if (allowed > (int64_t) len) {
- allowed = len;
- }
- if ((total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
- (int64_t) allowed)) == allowed) {
- buf = (char *) buf + total;
- conn->last_throttle_bytes += total;
- while (total < (int64_t) len && conn->ctx->stop_flag == 0) {
- allowed = conn->throttle > (int64_t) len - total ?
- (int64_t) len - total : conn->throttle;
- if ((n = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
- (int64_t) allowed)) != allowed) {
- break;
- }
- sleep(1);
- conn->last_throttle_bytes = allowed;
- conn->last_throttle_time = time(NULL);
- buf = (char *) buf + n;
- total += n;
- }
- }
- } else {
- total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
- (int64_t) len);
- }
- return (int) total;
-}
-
-/* Alternative alloc_vprintf() for non-compliant C runtimes */
-static int alloc_vprintf2(char **buf, const char *fmt, va_list ap)
-{
- va_list ap_copy;
- int size = MG_BUF_LEN;
- int len = -1;
-
- *buf = NULL;
- while (len == -1) {
- if (*buf) mg_free(*buf);
- *buf = (char *)mg_malloc(size *= 4);
- if (!*buf) break;
- va_copy(ap_copy, ap);
- len = vsnprintf(*buf, size, fmt, ap_copy);
- va_end(ap_copy);
- }
-
- return len;
-}
-
-/* Print message to buffer. If buffer is large enough to hold the message,
- return buffer. If buffer is to small, allocate large enough buffer on heap,
- and return allocated buffer. */
-static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap)
-{
- va_list ap_copy;
- int len;
-
- /* Windows is not standard-compliant, and vsnprintf() returns -1 if
- buffer is too small. Also, older versions of msvcrt.dll do not have
- _vscprintf(). However, if size is 0, vsnprintf() behaves correctly.
- Therefore, we make two passes: on first pass, get required message
- length.
- On second pass, actually print the message. */
- va_copy(ap_copy, ap);
- len = vsnprintf(NULL, 0, fmt, ap_copy);
- va_end(ap_copy);
-
- if (len < 0) {
- /* C runtime is not standard compliant, vsnprintf() returned -1.
- Switch to alternative code path that uses incremental allocations.
- */
- va_copy(ap_copy, ap);
- len = alloc_vprintf2(buf, fmt, ap);
- va_end(ap_copy);
- } else if (len > (int) size &&
- (size = len + 1) > 0 &&
- (*buf = (char *) mg_malloc(size)) == NULL) {
- len = -1; /* Allocation failed, mark failure */
- } else {
- va_copy(ap_copy, ap);
- IGNORE_UNUSED_RESULT(vsnprintf(*buf, size, fmt, ap_copy));
- va_end(ap_copy);
- }
-
- return len;
-}
-
-int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap)
-{
- char mem[MG_BUF_LEN], *buf = mem;
- int len;
-
- if ((len = alloc_vprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
- len = mg_write(conn, buf, (size_t) len);
- }
- if (buf != mem && buf != NULL) {
- mg_free(buf);
- }
-
- return len;
-}
-
-int mg_printf(struct mg_connection *conn, const char *fmt, ...)
-{
- va_list ap;
- int result;
-
- va_start(ap, fmt);
- result = mg_vprintf(conn, fmt, ap);
- va_end(ap);
-
- return result;
-}
-
-int mg_url_decode(const char *src, int src_len, char *dst,
- int dst_len, int is_form_url_encoded)
-{
- int i, j, a, b;
-#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
-
- for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) {
- if (i < src_len - 2 && src[i] == '%' &&
- isxdigit(* (const unsigned char *) (src + i + 1)) &&
- isxdigit(* (const unsigned char *) (src + i + 2))) {
- a = tolower(* (const unsigned char *) (src + i + 1));
- b = tolower(* (const unsigned char *) (src + i + 2));
- dst[j] = (char) ((HEXTOI(a) << 4) | HEXTOI(b));
- i += 2;
- } else if (is_form_url_encoded && src[i] == '+') {
- dst[j] = ' ';
- } else {
- dst[j] = src[i];
- }
- }
-
- dst[j] = '\0'; /* Null-terminate the destination */
-
- return i >= src_len ? j : -1;
-}
-
-int mg_get_var(const char *data, size_t data_len, const char *name,
- char *dst, size_t dst_len)
-{
- return mg_get_var2(data,data_len,name,dst,dst_len,0);
-}
-
-int mg_get_var2(const char *data, size_t data_len, const char *name,
- char *dst, size_t dst_len, size_t occurrence)
-{
- const char *p, *e, *s;
- size_t name_len;
- int len;
-
- if (dst == NULL || dst_len == 0) {
- len = -2;
- } else if (data == NULL || name == NULL || data_len == 0) {
- len = -1;
- dst[0] = '\0';
- } else {
- name_len = strlen(name);
- e = data + data_len;
- len = -1;
- dst[0] = '\0';
-
- /* data is "var1=val1&var2=val2...". Find variable first */
- for (p = data; p + name_len < e; p++) {
- if ((p == data || p[-1] == '&') && p[name_len] == '=' &&
- !mg_strncasecmp(name, p, name_len) && 0 == occurrence--) {
-
- /* Point p to variable value */
- p += name_len + 1;
-
- /* Point s to the end of the value */
- s = (const char *) memchr(p, '&', (size_t)(e - p));
- if (s == NULL) {
- s = e;
- }
- assert(s >= p);
-
- /* Decode variable into destination buffer */
- len = mg_url_decode(p, (int)(s - p), dst, (int)dst_len, 1);
-
- /* Redirect error code from -1 to -2 (destination buffer too
- small). */
- if (len == -1) {
- len = -2;
- }
- break;
- }
- }
- }
-
- return len;
-}
-
-int mg_get_cookie(const char *cookie_header, const char *var_name,
- char *dst, size_t dst_size)
-{
- const char *s, *p, *end;
- int name_len, len = -1;
-
- if (dst == NULL || dst_size == 0) {
- len = -2;
- } else if (var_name == NULL || (s = cookie_header) == NULL) {
- len = -1;
- dst[0] = '\0';
- } else {
- name_len = (int) strlen(var_name);
- end = s + strlen(s);
- dst[0] = '\0';
-
- for (; (s = mg_strcasestr(s, var_name)) != NULL; s += name_len) {
-
<TRUNCATED>
[5/8] celix git commit: CELIX-417: Refactors CMake usage for the RSA
bundles
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/civetweb/src/md5.inl
----------------------------------------------------------------------
diff --git a/remote_services/civetweb/src/md5.inl b/remote_services/civetweb/src/md5.inl
new file mode 100644
index 0000000..4da933d
--- /dev/null
+++ b/remote_services/civetweb/src/md5.inl
@@ -0,0 +1,461 @@
+/*
+ * This an amalgamation of md5.c and md5.h into a single file
+ * with all static declaration to reduce linker conflicts
+ * in Civetweb.
+ *
+ * The MD5_STATIC declaration was added to facilitate static
+ * inclusion.
+ * No Face Press, LLC
+ */
+
+/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.h is L. Peter Deutsch
+ <gh...@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Removed support for non-ANSI compilers; removed
+ references to Ghostscript; clarified derivation from RFC 1321;
+ now handles byte order either statically or dynamically.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+ added conditionalization for C++ compilation from Martin
+ Purschke <pu...@bnl.gov>.
+ 1999-05-03 lpd Original version.
+ */
+
+#ifndef md5_INCLUDED
+# define md5_INCLUDED
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+ md5_word_t count[2]; /* message length in bits, lsw first */
+ md5_word_t abcd[4]; /* digest buffer */
+ md5_byte_t buf[64]; /* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Initialize the algorithm. */
+MD5_STATIC void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+MD5_STATIC void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+
+/* Finish the message and return the digest. */
+MD5_STATIC void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
+
+/*
+ Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.c is L. Peter Deutsch
+ <gh...@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+ either statically or dynamically; added missing #include <string.h>
+ in library.
+ 2002-03-11 lpd Corrected argument list for main(), and added int return
+ type, in test program and T value program.
+ 2002-02-21 lpd Added missing #include <stdio.h> in test program.
+ 2000-07-03 lpd Patched to eliminate warnings about "constant is
+ unsigned in ANSI C, signed in traditional"; made test program
+ self-checking.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+ 1999-05-03 lpd Original version.
+ */
+
+#ifndef MD5_STATIC
+#include <string.h>
+#endif
+
+#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#ifdef ARCH_IS_BIG_ENDIAN
+# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
+#else
+# define BYTE_ORDER 0
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3 0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6 0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9 0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13 0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16 0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19 0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22 0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25 0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28 0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31 0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35 0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38 0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41 0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44 0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47 0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50 0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53 0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57 0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60 0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63 0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+ md5_word_t
+ a = pms->abcd[0], b = pms->abcd[1],
+ c = pms->abcd[2], d = pms->abcd[3];
+ md5_word_t t;
+#if BYTE_ORDER > 0
+ /* Define storage only for big-endian CPUs. */
+ md5_word_t X[16];
+#else
+ /* Define storage for little-endian or both types of CPUs. */
+ md5_word_t xbuf[16];
+ const md5_word_t *X;
+#endif
+
+ {
+#if BYTE_ORDER == 0
+ /*
+ * Determine dynamically whether this is a big-endian or
+ * little-endian machine, since we can use a more efficient
+ * algorithm on the latter.
+ */
+ static const int w = 1;
+
+ if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0 /* little-endian */
+ {
+ /*
+ * On little-endian machines, we can process properly aligned
+ * data without copying it.
+ */
+ if (!((data - (const md5_byte_t *)0) & 3)) {
+ /* data are properly aligned */
+ X = (const md5_word_t *)data;
+ } else {
+ /* not aligned */
+ memcpy(xbuf, data, 64);
+ X = xbuf;
+ }
+ }
+#endif
+#if BYTE_ORDER == 0
+ else /* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0 /* big-endian */
+ {
+ /*
+ * On big-endian machines, we must arrange the bytes in the
+ * right order.
+ */
+ const md5_byte_t *xp = data;
+ int i;
+
+# if BYTE_ORDER == 0
+ X = xbuf; /* (dynamic only) */
+# else
+# define xbuf X /* (static only) */
+# endif
+ for (i = 0; i < 16; ++i, xp += 4)
+ xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+ }
+#endif
+ }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + F(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 7, T1);
+ SET(d, a, b, c, 1, 12, T2);
+ SET(c, d, a, b, 2, 17, T3);
+ SET(b, c, d, a, 3, 22, T4);
+ SET(a, b, c, d, 4, 7, T5);
+ SET(d, a, b, c, 5, 12, T6);
+ SET(c, d, a, b, 6, 17, T7);
+ SET(b, c, d, a, 7, 22, T8);
+ SET(a, b, c, d, 8, 7, T9);
+ SET(d, a, b, c, 9, 12, T10);
+ SET(c, d, a, b, 10, 17, T11);
+ SET(b, c, d, a, 11, 22, T12);
+ SET(a, b, c, d, 12, 7, T13);
+ SET(d, a, b, c, 13, 12, T14);
+ SET(c, d, a, b, 14, 17, T15);
+ SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + G(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 1, 5, T17);
+ SET(d, a, b, c, 6, 9, T18);
+ SET(c, d, a, b, 11, 14, T19);
+ SET(b, c, d, a, 0, 20, T20);
+ SET(a, b, c, d, 5, 5, T21);
+ SET(d, a, b, c, 10, 9, T22);
+ SET(c, d, a, b, 15, 14, T23);
+ SET(b, c, d, a, 4, 20, T24);
+ SET(a, b, c, d, 9, 5, T25);
+ SET(d, a, b, c, 14, 9, T26);
+ SET(c, d, a, b, 3, 14, T27);
+ SET(b, c, d, a, 8, 20, T28);
+ SET(a, b, c, d, 13, 5, T29);
+ SET(d, a, b, c, 2, 9, T30);
+ SET(c, d, a, b, 7, 14, T31);
+ SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + H(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 5, 4, T33);
+ SET(d, a, b, c, 8, 11, T34);
+ SET(c, d, a, b, 11, 16, T35);
+ SET(b, c, d, a, 14, 23, T36);
+ SET(a, b, c, d, 1, 4, T37);
+ SET(d, a, b, c, 4, 11, T38);
+ SET(c, d, a, b, 7, 16, T39);
+ SET(b, c, d, a, 10, 23, T40);
+ SET(a, b, c, d, 13, 4, T41);
+ SET(d, a, b, c, 0, 11, T42);
+ SET(c, d, a, b, 3, 16, T43);
+ SET(b, c, d, a, 6, 23, T44);
+ SET(a, b, c, d, 9, 4, T45);
+ SET(d, a, b, c, 12, 11, T46);
+ SET(c, d, a, b, 15, 16, T47);
+ SET(b, c, d, a, 2, 23, T48);
+#undef SET
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + I(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 6, T49);
+ SET(d, a, b, c, 7, 10, T50);
+ SET(c, d, a, b, 14, 15, T51);
+ SET(b, c, d, a, 5, 21, T52);
+ SET(a, b, c, d, 12, 6, T53);
+ SET(d, a, b, c, 3, 10, T54);
+ SET(c, d, a, b, 10, 15, T55);
+ SET(b, c, d, a, 1, 21, T56);
+ SET(a, b, c, d, 8, 6, T57);
+ SET(d, a, b, c, 15, 10, T58);
+ SET(c, d, a, b, 6, 15, T59);
+ SET(b, c, d, a, 13, 21, T60);
+ SET(a, b, c, d, 4, 6, T61);
+ SET(d, a, b, c, 11, 10, T62);
+ SET(c, d, a, b, 2, 15, T63);
+ SET(b, c, d, a, 9, 21, T64);
+#undef SET
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ pms->abcd[0] += a;
+ pms->abcd[1] += b;
+ pms->abcd[2] += c;
+ pms->abcd[3] += d;
+}
+
+MD5_STATIC void
+md5_init(md5_state_t *pms)
+{
+ pms->count[0] = pms->count[1] = 0;
+ pms->abcd[0] = 0x67452301;
+ pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+ pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+ pms->abcd[3] = 0x10325476;
+}
+
+MD5_STATIC void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+ const md5_byte_t *p = data;
+ int left = nbytes;
+ int offset = (pms->count[0] >> 3) & 63;
+ md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+ if (nbytes <= 0)
+ return;
+
+ /* Update the message length. */
+ pms->count[1] += nbytes >> 29;
+ pms->count[0] += nbits;
+ if (pms->count[0] < nbits)
+ pms->count[1]++;
+
+ /* Process an initial partial block. */
+ if (offset) {
+ int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+ memcpy(pms->buf + offset, p, copy);
+ if (offset + copy < 64)
+ return;
+ p += copy;
+ left -= copy;
+ md5_process(pms, pms->buf);
+ }
+
+ /* Process full blocks. */
+ for (; left >= 64; p += 64, left -= 64)
+ md5_process(pms, p);
+
+ /* Process a final partial block. */
+ if (left)
+ memcpy(pms->buf, p, left);
+}
+
+MD5_STATIC void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+ static const md5_byte_t pad[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ md5_byte_t data[8];
+ int i;
+
+ /* Save the length before padding. */
+ for (i = 0; i < 8; ++i)
+ data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+ /* Pad to 56 bytes mod 64. */
+ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+ /* Append the length. */
+ md5_append(pms, data, 8);
+ for (i = 0; i < 16; ++i)
+ digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/CMakeLists.txt b/remote_services/discovery_common/CMakeLists.txt
index 9388c90..5b28b13 100644
--- a/remote_services/discovery_common/CMakeLists.txt
+++ b/remote_services/discovery_common/CMakeLists.txt
@@ -18,16 +18,22 @@
find_package(LibXml2 REQUIRED)
-add_library(discovery_common STATIC
+add_library(discovery_common OBJECT
src/discovery.c
src/discovery_activator.c
src/endpoint_descriptor_reader.c
src/endpoint_descriptor_writer.c
src/endpoint_discovery_poller.c
src/endpoint_discovery_server.c
- src/civetweb.c
)
-target_include_directories(discovery_common PUBLIC include)
-target_include_directories(discovery_common PRIVATE src ${LIBXML2_INCLUDE_DIR})
-target_link_libraries(discovery_common PRIVATE ${LIBXML2_LIBRARIES} Celix::framework)
-target_link_libraries(discovery_common PUBLIC Celix::log_helper Celix::remote_service_admin_api)
\ No newline at end of file
+target_include_directories(discovery_common PUBLIC
+ include src
+ $<TARGET_PROPERTY:Celix::framework,INTERFACE_INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::utils,INTERFACE_INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::log_helper,INTERFACE_INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::remote_service_admin_api,INTERFACE_INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Celix::remote_service_admin_api,INTERFACE_INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:civetweb,INCLUDE_DIRECTORIES>
+ ${LIBXML2_INCLUDE_DIR})
+
+add_library(Celix::discovery_common ALIAS discovery_common)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/include/civetweb.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/civetweb.h b/remote_services/discovery_common/include/civetweb.h
deleted file mode 100644
index 61a8e98..0000000
--- a/remote_services/discovery_common/include/civetweb.h
+++ /dev/null
@@ -1,657 +0,0 @@
-/* Copyright (c) 2013-2014 the Civetweb developers
- * Copyright (c) 2004-2013 Sergey Lyubka
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef CIVETWEB_HEADER_INCLUDED
-#define CIVETWEB_HEADER_INCLUDED
-
-#ifndef CIVETWEB_VERSION
-#define CIVETWEB_VERSION "1.7"
-#endif
-
-#ifndef CIVETWEB_API
- #if defined(_WIN32)
- #if defined(CIVETWEB_DLL_EXPORTS)
- #define CIVETWEB_API __declspec(dllexport)
- #elif defined(CIVETWEB_DLL_IMPORTS)
- #define CIVETWEB_API __declspec(dllimport)
- #else
- #define CIVETWEB_API
- #endif
- #else
- #define CIVETWEB_API
- #endif
-#endif
-
-#include <stdio.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-struct mg_context; /* Handle for the HTTP service itself */
-struct mg_connection; /* Handle for the individual connection */
-
-
-/* This structure contains information about the HTTP request. */
-struct mg_request_info {
- const char *request_method; /* "GET", "POST", etc */
- const char *uri; /* URL-decoded URI */
- const char *http_version; /* E.g. "1.0", "1.1" */
- const char *query_string; /* URL part after '?', not including '?', or
- NULL */
- const char *remote_user; /* Authenticated user, or NULL if no auth
- used */
- char remote_addr[48]; /* Client's IP address as a string. */
- long remote_ip; /* Client's IP address. Deprecated: use remote_addr instead */
-
- long long content_length; /* Length (in bytes) of the request body,
- can be -1 if no length was given. */
- int remote_port; /* Client's port */
- int is_ssl; /* 1 if SSL-ed, 0 if not */
- void *user_data; /* User data pointer passed to mg_start() */
- void *conn_data; /* Connection-specific user data */
-
- int num_headers; /* Number of HTTP headers */
- struct mg_header {
- const char *name; /* HTTP header name */
- const char *value; /* HTTP header value */
- } http_headers[64]; /* Maximum 64 headers */
-};
-
-
-/* This structure needs to be passed to mg_start(), to let civetweb know
- which callbacks to invoke. For a detailed description, see
- https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md */
-struct mg_callbacks {
- /* Called when civetweb has received new HTTP request.
- If the callback returns one, it must process the request
- by sending valid HTTP headers and a body. Civetweb will not do
- any further processing. Otherwise it must return zero.
- Note that since V1.7 the "begin_request" function is called
- before an authorization check. If an authorization check is
- required, use a request_handler instead.
- Return value:
- 0: civetweb will process the request itself. In this case,
- the callback must not send any data to the client.
- 1: callback already processed the request. Civetweb will
- not send any data after the callback returned. */
- int (*begin_request)(struct mg_connection *);
-
- /* Called when civetweb has finished processing request. */
- void (*end_request)(const struct mg_connection *, int reply_status_code);
-
- /* Called when civetweb is about to log a message. If callback returns
- non-zero, civetweb does not log anything. */
- int (*log_message)(const struct mg_connection *, const char *message);
-
- /* Called when civetweb initializes SSL library.
- Parameters:
- user_data: parameter user_data passed when starting the server.
- Return value:
- 0: civetweb will set up the SSL certificate.
- 1: civetweb assumes the callback already set up the certificate.
- -1: initializing ssl fails. */
- int (*init_ssl)(void *ssl_context, void *user_data);
-
- /* Called when websocket request is received, before websocket handshake.
- Return value:
- 0: civetweb proceeds with websocket handshake.
- 1: connection is closed immediately. */
- int (*websocket_connect)(const struct mg_connection *);
-
- /* Called when websocket handshake is successfully completed, and
- connection is ready for data exchange. */
- void (*websocket_ready)(struct mg_connection *);
-
- /* Called when data frame has been received from the client.
- Parameters:
- bits: first byte of the websocket frame, see websocket RFC at
- http://tools.ietf.org/html/rfc6455, section 5.2
- data, data_len: payload, with mask (if any) already applied.
- Return value:
- 1: keep this websocket connection open.
- 0: close this websocket connection. */
- int (*websocket_data)(struct mg_connection *, int bits,
- char *data, size_t data_len);
-
- /* Called when civetweb is closing a connection. The per-context mutex is
- locked when this is invoked. This is primarily useful for noting when
- a websocket is closing and removing it from any application-maintained
- list of clients. */
- void (*connection_close)(struct mg_connection *);
-
- /* Called when civetweb tries to open a file. Used to intercept file open
- calls, and serve file data from memory instead.
- Parameters:
- path: Full path to the file to open.
- data_len: Placeholder for the file size, if file is served from
- memory.
- Return value:
- NULL: do not serve file from memory, proceed with normal file open.
- non-NULL: pointer to the file contents in memory. data_len must be
- initilized with the size of the memory block. */
- const char * (*open_file)(const struct mg_connection *,
- const char *path, size_t *data_len);
-
- /* Called when civetweb is about to serve Lua server page, if
- Lua support is enabled.
- Parameters:
- lua_context: "lua_State *" pointer. */
- void (*init_lua)(struct mg_connection *, void *lua_context);
-
- /* Called when civetweb has uploaded a file to a temporary directory as a
- result of mg_upload() call.
- Parameters:
- file_name: full path name to the uploaded file. */
- void (*upload)(struct mg_connection *, const char *file_name);
-
- /* Called when civetweb is about to send HTTP error to the client.
- Implementing this callback allows to create custom error pages.
- Parameters:
- status: HTTP error status code.
- Return value:
- 1: run civetweb error handler.
- 0: callback already handled the error. */
- int (*http_error)(struct mg_connection *, int status);
-
- /* Called after civetweb context has been created, before requests
- are processed.
- Parameters:
- ctx: context handle */
- void (*init_context)(struct mg_context * ctx);
-
- /* Called when civetweb context is deleted.
- Parameters:
- ctx: context handle */
- void (*exit_context)(struct mg_context * ctx);
-};
-
-
-/* Start web server.
-
- Parameters:
- callbacks: mg_callbacks structure with user-defined callbacks.
- options: NULL terminated list of option_name, option_value pairs that
- specify Civetweb configuration parameters.
-
- Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
- processing is required for these, signal handlers must be set up
- after calling mg_start().
-
-
- Example:
- const char *options[] = {
- "document_root", "/var/www",
- "listening_ports", "80,443s",
- NULL
- };
- struct mg_context *ctx = mg_start(&my_func, NULL, options);
-
- Refer to https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md
- for the list of valid option and their possible values.
-
- Return:
- web server context, or NULL on error. */
-CIVETWEB_API struct mg_context *mg_start(const struct mg_callbacks *callbacks,
- void *user_data,
- const char **configuration_options);
-
-
-/* Stop the web server.
-
- Must be called last, when an application wants to stop the web server and
- release all associated resources. This function blocks until all Civetweb
- threads are stopped. Context pointer becomes invalid. */
-CIVETWEB_API void mg_stop(struct mg_context *);
-
-
-/* mg_request_handler
-
- Called when a new request comes in. This callback is URI based
- and configured with mg_set_request_handler().
-
- Parameters:
- conn: current connection information.
- cbdata: the callback data configured with mg_set_request_handler().
- Returns:
- 0: the handler could not handle the request, so fall through.
- 1: the handler processed the request. */
-typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata);
-
-
-/* mg_set_request_handler
-
- Sets or removes a URI mapping for a request handler.
-
- URI's are ordered and prefixed URI's are supported. For example,
- consider two URIs: /a/b and /a
- /a matches /a
- /a/b matches /a/b
- /a/c matches /a
-
- Parameters:
- ctx: server context
- uri: the URI to configure
- handler: the callback handler to use when the URI is requested.
- If NULL, the URI will be removed.
- cbdata: the callback data to give to the handler when it s requested. */
-CIVETWEB_API void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata);
-
-
-/* Get the value of particular configuration parameter.
- The value returned is read-only. Civetweb does not allow changing
- configuration at run time.
- If given parameter name is not valid, NULL is returned. For valid
- names, return value is guaranteed to be non-NULL. If parameter is not
- set, zero-length string is returned. */
-CIVETWEB_API const char *mg_get_option(const struct mg_context *ctx, const char *name);
-
-
-/* Get context from connection. */
-CIVETWEB_API struct mg_context *mg_get_context(struct mg_connection *conn);
-
-
-/* Get user data passed to mg_start from context. */
-CIVETWEB_API void *mg_get_user_data(struct mg_context *ctx);
-
-
-#if defined(MG_LEGACY_INTERFACE)
-/* Return array of strings that represent valid configuration options.
- For each option, option name and default value is returned, i.e. the
- number of entries in the array equals to number_of_options x 2.
- Array is NULL terminated. */
-/* Deprecated: Use mg_get_valid_options instead. */
-CIVETWEB_API const char **mg_get_valid_option_names(void);
-#endif
-
-
-struct mg_option {
- const char * name;
- int type;
- const char * default_value;
-};
-
-enum {
- CONFIG_TYPE_UNKNOWN = 0x0,
- CONFIG_TYPE_NUMBER = 0x1,
- CONFIG_TYPE_STRING = 0x2,
- CONFIG_TYPE_FILE = 0x3,
- CONFIG_TYPE_DIRECTORY = 0x4,
- CONFIG_TYPE_BOOLEAN = 0x5,
- CONFIG_TYPE_EXT_PATTERN = 0x6
-};
-
-
-/* Return array of struct mg_option, representing all valid configuration
- options of civetweb.c.
- The array is terminated by a NULL name option. */
-CIVETWEB_API const struct mg_option *mg_get_valid_options(void);
-
-
-/* Get the list of ports that civetweb is listening on.
- size is the size of the ports int array and ssl int array to fill.
- It is the caller's responsibility to make sure ports and ssl each
- contain at least size int elements worth of memory to write into.
- Return value is the number of ports and ssl information filled in.
- The value returned is read-only. Civetweb does not allow changing
- configuration at run time. */
-CIVETWEB_API size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl);
-
-
-/* Add, edit or delete the entry in the passwords file.
-
- This function allows an application to manipulate .htpasswd files on the
- fly by adding, deleting and changing user records. This is one of the
- several ways of implementing authentication on the server side. For another,
- cookie-based way please refer to the examples/chat in the source tree.
-
- If password is not NULL, entry is added (or modified if already exists).
- If password is NULL, entry is deleted.
-
- Return:
- 1 on success, 0 on error. */
-CIVETWEB_API int mg_modify_passwords_file(const char *passwords_file_name,
- const char *domain,
- const char *user,
- const char *password);
-
-
-/* Return information associated with the request. */
-CIVETWEB_API struct mg_request_info *mg_get_request_info(struct mg_connection *);
-
-
-/* Send data to the client.
- Return:
- 0 when the connection has been closed
- -1 on error
- >0 number of bytes written on success */
-CIVETWEB_API int mg_write(struct mg_connection *, const void *buf, size_t len);
-
-
-/* Send data to a websocket client wrapped in a websocket frame. Uses mg_lock
- to ensure that the transmission is not interrupted, i.e., when the
- application is proactively communicating and responding to a request
- simultaneously.
-
- Send data to a websocket client wrapped in a websocket frame.
- This function is available when civetweb is compiled with -DUSE_WEBSOCKET
-
- Return:
- 0 when the connection has been closed
- -1 on error
- >0 number of bytes written on success */
-CIVETWEB_API int mg_websocket_write(struct mg_connection* conn, int opcode,
- const char *data, size_t data_len);
-
-
-/* Blocks until unique access is obtained to this connection. Intended for use
- with websockets only.
- Invoke this before mg_write or mg_printf when communicating with a
- websocket if your code has server-initiated communication as well as
- communication in direct response to a message. */
-CIVETWEB_API void mg_lock_connection(struct mg_connection* conn);
-CIVETWEB_API void mg_unlock_connection(struct mg_connection* conn);
-
-#if defined(MG_LEGACY_INTERFACE)
-#define mg_lock mg_lock_connection
-#define mg_unlock mg_unlock_connection
-#endif
-
-/* Lock server context. This lock may be used to protect ressources
- that are shared between different connection/worker threads. */
-CIVETWEB_API void mg_lock_context(struct mg_context* ctx);
-CIVETWEB_API void mg_unlock_context(struct mg_context* ctx);
-
-
-/* Opcodes, from http://tools.ietf.org/html/rfc6455 */
-enum {
- WEBSOCKET_OPCODE_CONTINUATION = 0x0,
- WEBSOCKET_OPCODE_TEXT = 0x1,
- WEBSOCKET_OPCODE_BINARY = 0x2,
- WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
- WEBSOCKET_OPCODE_PING = 0x9,
- WEBSOCKET_OPCODE_PONG = 0xa
-};
-
-
-/* Macros for enabling compiler-specific checks forprintf-like arguments. */
-#undef PRINTF_FORMAT_STRING
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-#include <sal.h>
-#if defined(_MSC_VER) && _MSC_VER > 1400
-#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
-#else
-#define PRINTF_FORMAT_STRING(s) __format_string s
-#endif
-#else
-#define PRINTF_FORMAT_STRING(s) s
-#endif
-
-#ifdef __GNUC__
-#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
-#else
-#define PRINTF_ARGS(x, y)
-#endif
-
-/* Send data to the client usingprintf() semantics.
- Works exactly like mg_write(), but allows to do message formatting. */
-CIVETWEB_API int mg_printf(struct mg_connection *,
- PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
-
-
-/* Send contents of the entire file together with HTTP headers. */
-CIVETWEB_API void mg_send_file(struct mg_connection *conn, const char *path);
-
-
-/* Read data from the remote end, return number of bytes read.
- Return:
- 0 connection has been closed by peer. No more data could be read.
- < 0 read error. No more data could be read from the connection.
- > 0 number of bytes read into the buffer. */
-CIVETWEB_API int mg_read(struct mg_connection *, void *buf, size_t len);
-
-
-/* Get the value of particular HTTP header.
-
- This is a helper function. It traverses request_info->http_headers array,
- and if the header is present in the array, returns its value. If it is
- not present, NULL is returned. */
-CIVETWEB_API const char *mg_get_header(const struct mg_connection *, const char *name);
-
-
-/* Get a value of particular form variable.
-
- Parameters:
- data: pointer to form-uri-encoded buffer. This could be either POST data,
- or request_info.query_string.
- data_len: length of the encoded data.
- var_name: variable name to decode from the buffer
- dst: destination buffer for the decoded variable
- dst_len: length of the destination buffer
-
- Return:
- On success, length of the decoded variable.
- On error:
- -1 (variable not found).
- -2 (destination buffer is NULL, zero length or too small to hold the
- decoded variable).
-
- Destination buffer is guaranteed to be '\0' - terminated if it is not
- NULL or zero length. */
-CIVETWEB_API int mg_get_var(const char *data, size_t data_len,
- const char *var_name, char *dst, size_t dst_len);
-
-
-/* Get a value of particular form variable.
-
- Parameters:
- data: pointer to form-uri-encoded buffer. This could be either POST data,
- or request_info.query_string.
- data_len: length of the encoded data.
- var_name: variable name to decode from the buffer
- dst: destination buffer for the decoded variable
- dst_len: length of the destination buffer
- occurrence: which occurrence of the variable, 0 is the first, 1 the
- second...
- this makes it possible to parse a query like
- b=x&a=y&a=z which will have occurrence values b:0, a:0 and a:1
-
- Return:
- On success, length of the decoded variable.
- On error:
- -1 (variable not found).
- -2 (destination buffer is NULL, zero length or too small to hold the
- decoded variable).
-
- Destination buffer is guaranteed to be '\0' - terminated if it is not
- NULL or zero length. */
-CIVETWEB_API int mg_get_var2(const char *data, size_t data_len,
- const char *var_name, char *dst, size_t dst_len, size_t occurrence);
-
-
-/* Fetch value of certain cookie variable into the destination buffer.
-
- Destination buffer is guaranteed to be '\0' - terminated. In case of
- failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
- parameter. This function returns only first occurrence.
-
- Return:
- On success, value length.
- On error:
- -1 (either "Cookie:" header is not present at all or the requested
- parameter is not found).
- -2 (destination buffer is NULL, zero length or too small to hold the
- value). */
-CIVETWEB_API int mg_get_cookie(const char *cookie, const char *var_name,
- char *buf, size_t buf_len);
-
-
-/* Download data from the remote web server.
- host: host name to connect to, e.g. "foo.com", or "10.12.40.1".
- port: port number, e.g. 80.
- use_ssl: wether to use SSL connection.
- error_buffer, error_buffer_size: error message placeholder.
- request_fmt,...: HTTP request.
- Return:
- On success, valid pointer to the new connection, suitable for mg_read().
- On error, NULL. error_buffer contains error message.
- Example:
- char ebuf[100];
- struct mg_connection *conn;
- conn = mg_download("google.com", 80, 0, ebuf, sizeof(ebuf),
- "%s", "GET / HTTP/1.0\r\nHost: google.com\r\n\r\n");
- */
-CIVETWEB_API struct mg_connection *mg_download(const char *host, int port, int use_ssl,
- char *error_buffer, size_t error_buffer_size,
- PRINTF_FORMAT_STRING(const char *request_fmt),
- ...) PRINTF_ARGS(6, 7);
-
-
-/* Close the connection opened by mg_download(). */
-CIVETWEB_API void mg_close_connection(struct mg_connection *conn);
-
-
-/* File upload functionality. Each uploaded file gets saved into a temporary
- file and MG_UPLOAD event is sent.
- Return number of uploaded files. */
-CIVETWEB_API int mg_upload(struct mg_connection *conn, const char *destination_dir);
-
-
-/* Convenience function -- create detached thread.
- Return: 0 on success, non-0 on error. */
-typedef void * (*mg_thread_func_t)(void *);
-CIVETWEB_API int mg_start_thread(mg_thread_func_t f, void *p);
-
-
-/* Return builtin mime type for the given file name.
- For unrecognized extensions, "text/plain" is returned. */
-CIVETWEB_API const char *mg_get_builtin_mime_type(const char *file_name);
-
-
-/* Return Civetweb version. */
-CIVETWEB_API const char *mg_version(void);
-
-
-/* URL-decode input buffer into destination buffer.
- 0-terminate the destination buffer.
- form-url-encoded data differs from URI encoding in a way that it
- uses '+' as character for space, see RFC 1866 section 8.2.1
- http://ftp.ics.uci.edu/pub/ietf/html/rfc1866.txt
- Return: length of the decoded data, or -1 if dst buffer is too small. */
-CIVETWEB_API int mg_url_decode(const char *src, int src_len, char *dst,
- int dst_len, int is_form_url_encoded);
-
-
-/* URL-encode input buffer into destination buffer.
- returns the length of the resulting buffer or -1
- is the buffer is too small. */
-CIVETWEB_API int mg_url_encode(const char *src, char *dst, size_t dst_len);
-
-
-/* MD5 hash given strings.
- Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
- ASCIIz strings. When function returns, buf will contain human-readable
- MD5 hash. Example:
- char buf[33];
- mg_md5(buf, "aa", "bb", NULL); */
-CIVETWEB_API char *mg_md5(char buf[33], ...);
-
-
-/* Print error message to the opened error log stream.
- This utilizes the provided logging configuration.
- conn: connection
- fmt: format string without the line return
- ...: variable argument list
- Example:
- mg_cry(conn,"i like %s", "logging"); */
-CIVETWEB_API void mg_cry(struct mg_connection *conn,
- PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
-
-
-/* utility method to compare two buffers, case incensitive. */
-CIVETWEB_API int mg_strncasecmp(const char *s1, const char *s2, size_t len);
-
-/* Connect to a websocket as a client
- Parameters:
- host: host to connect to, i.e. "echo.websocket.org" or "192.168.1.1" or "localhost"
- port: server port
- use_ssl: make a secure connection to server
- error_buffer, error_buffer_size: buffer for an error message
- path: server path you are trying to connect to, i.e. if connection to localhost/app, path should be "/app"
- origin: value of the Origin HTTP header
- data_func: callback that should be used when data is received from the server
- user_data: user supplied argument
-
- Return:
- On success, valid mg_connection object.
- On error, NULL. Se error_buffer for details.
-*/
-
-typedef int (*websocket_data_func)(struct mg_connection *, int bits,
- char *data, size_t data_len);
-
-typedef void (*websocket_close_func)(struct mg_connection *);
-
-CIVETWEB_API struct mg_connection *mg_connect_websocket_client(const char *host, int port, int use_ssl,
- char *error_buffer, size_t error_buffer_size,
- const char *path, const char *origin,
- websocket_data_func data_func, websocket_close_func close_func,
- void * user_data);
-
-/* Connect to a TCP server as a client (can be used to connect to a HTTP server)
- Parameters:
- host: host to connect to, i.e. "www.wikipedia.org" or "192.168.1.1" or "localhost"
- port: server port
- use_ssl: make a secure connection to server
- error_buffer, error_buffer_size: buffer for an error message
-
- Return:
- On success, valid mg_connection object.
- On error, NULL. Se error_buffer for details.
-*/
-CIVETWEB_API struct mg_connection *mg_connect_client(const char *host, int port, int use_ssl,
- char *error_buffer, size_t error_buffer_size);
-
-
-enum {
- TIMEOUT_INFINITE = -1
-};
-
-/* Wait for a response from the server
- Parameters:
- conn: connection
- ebuf, ebuf_len: error message placeholder.
- timeout: time to wait for a response in milliseconds (if < 0 then wait forever)
-
- Return:
- On success, >= 0
- On error/timeout, < 0
-*/
-CIVETWEB_API int mg_get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int timeout);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* CIVETWEB_HEADER_INCLUDED */
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/include/discovery.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/discovery.h b/remote_services/discovery_common/include/discovery.h
index ee79caf..ede3d5e 100644
--- a/remote_services/discovery_common/include/discovery.h
+++ b/remote_services/discovery_common/include/discovery.h
@@ -27,12 +27,18 @@
#ifndef DISCOVERY_H_
#define DISCOVERY_H_
+#include "discovery_type.h"
#include "bundle_context.h"
#include "service_reference.h"
#include "endpoint_description.h"
#include "endpoint_listener.h"
+#include "endpoint_discovery_server.h"
+#include "endpoint_discovery_poller.h"
+
+#include "log_helper.h"
+
#define DISCOVERY_SERVER_INTERFACE "DISCOVERY_CFG_SERVER_INTERFACE"
#define DISCOVERY_SERVER_IP "DISCOVERY_CFG_SERVER_IP"
#define DISCOVERY_SERVER_PORT "DISCOVERY_CFG_SERVER_PORT"
@@ -40,7 +46,22 @@
#define DISCOVERY_POLL_ENDPOINTS "DISCOVERY_CFG_POLL_ENDPOINTS"
#define DISCOVERY_SERVER_MAX_EP "DISCOVERY_CFG_SERVER_MAX_EP"
-typedef struct discovery *discovery_pt;
+struct discovery {
+ bundle_context_t* context;
+
+ celix_thread_mutex_t listenerReferencesMutex;
+ celix_thread_mutex_t discoveredServicesMutex;
+
+ hash_map_t* listenerReferences; //key=serviceReference, value=nop
+ hash_map_t* discoveredServices; //key=endpointId (string), value=endpoint_description_pt
+
+ endpoint_discovery_poller_t* poller;
+ endpoint_discovery_server_t* server;
+
+ log_helper_t* loghelper;
+
+ discovery_impl_t* pImpl;
+};
/* those one could be put into a general discovery.h - file */
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/include/discovery_type.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/discovery_type.h b/remote_services/discovery_common/include/discovery_type.h
new file mode 100644
index 0000000..222a495
--- /dev/null
+++ b/remote_services/discovery_common/include/discovery_type.h
@@ -0,0 +1,27 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef DISCOVERY_TYPE_H_
+#define DISCOVERY_TYPE_H_
+
+typedef struct discovery discovery_t;
+typedef struct discovery* discovery_pt;
+typedef struct discovery_impl discovery_impl_t;
+
+#endif //DISCOVERY_TYPE_H_
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/include/endpoint_discovery_poller.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_discovery_poller.h b/remote_services/discovery_common/include/endpoint_discovery_poller.h
index d344e55..3c537f1 100644
--- a/remote_services/discovery_common/include/endpoint_discovery_poller.h
+++ b/remote_services/discovery_common/include/endpoint_discovery_poller.h
@@ -28,9 +28,12 @@
#define ENDPOINT_DISCOVERY_POLLER_H_
#include "celix_errno.h"
-#include "discovery.h"
+#include "discovery_type.h"
#include "log_helper.h"
+typedef struct endpoint_discovery_poller endpoint_discovery_poller_t;
+typedef struct endpoint_discovery_poller *endpoint_discovery_poller_pt;
+
struct endpoint_discovery_poller {
discovery_pt discovery;
hash_map_pt entries;
@@ -43,9 +46,7 @@ struct endpoint_discovery_poller {
volatile bool running;
};
-typedef struct endpoint_discovery_poller *endpoint_discovery_poller_pt;
-
-celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_poller_pt *poller);
+celix_status_t endpointDiscoveryPoller_create(discovery_pt discovery, bundle_context_pt context, const char* defaultPollEndpoints, endpoint_discovery_poller_pt *poller);
celix_status_t endpointDiscoveryPoller_destroy(endpoint_discovery_poller_pt poller);
celix_status_t endpointDiscoveryPoller_addDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url);
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/discovery_common/include/endpoint_discovery_server.h
----------------------------------------------------------------------
diff --git a/remote_services/discovery_common/include/endpoint_discovery_server.h b/remote_services/discovery_common/include/endpoint_discovery_server.h
index 51082b5..d70c145 100644
--- a/remote_services/discovery_common/include/endpoint_discovery_server.h
+++ b/remote_services/discovery_common/include/endpoint_discovery_server.h
@@ -28,8 +28,9 @@
#define ENDPOINT_DISCOVERY_SERVER_H_
#include "celix_errno.h"
-#include "discovery.h"
+#include "discovery_type.h"
+typedef struct endpoint_discovery_server endpoint_discovery_server_t;
typedef struct endpoint_discovery_server *endpoint_discovery_server_pt;
/**
@@ -40,7 +41,13 @@ typedef struct endpoint_discovery_server *endpoint_discovery_server_pt;
* @param server [out] the pointer to the created instance.
* @return CELIX_SUCCESS when successful.
*/
-celix_status_t endpointDiscoveryServer_create(discovery_pt discovery, bundle_context_pt context, endpoint_discovery_server_pt *server);
+celix_status_t endpointDiscoveryServer_create(
+ discovery_pt discovery,
+ bundle_context_pt context,
+ const char* defaultServerPath,
+ const char* defaultServerPort,
+ const char* defaultServerIp,
+ endpoint_discovery_server_pt *server);
/**
* Stops and destroys a given instance of an endpoint discovery server.
[6/8] celix git commit: CELIX-417: Refactors CMake usage for the RSA
bundles
Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/27a2aa75/remote_services/civetweb/src/civetweb.c
----------------------------------------------------------------------
diff --git a/remote_services/civetweb/src/civetweb.c b/remote_services/civetweb/src/civetweb.c
new file mode 100644
index 0000000..a6093b7
--- /dev/null
+++ b/remote_services/civetweb/src/civetweb.c
@@ -0,0 +1,7907 @@
+ /* Copyright (c) 2013-2015 the Civetweb developers
+ * Copyright (c) 2004-2013 Sergey Lyubka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if defined(_WIN32)
+#if !defined(_CRT_SECURE_NO_WARNINGS)
+#define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005 */
+#endif
+#else
+#ifdef __linux__
+#define _XOPEN_SOURCE 600 /* For flockfile() on Linux */
+#endif
+#ifndef _LARGEFILE_SOURCE
+#define _LARGEFILE_SOURCE /* For fseeko(), ftello() */
+#endif
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64 /* Use 64-bit file offsets by default */
+#endif
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS /* <inttypes.h> wants this for C++ */
+#endif
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS /* C++ wants that for INT64_MAX */
+#endif
+#endif
+
+#if defined (_MSC_VER)
+/* 'type cast' : conversion from 'int' to 'HANDLE' of greater size */
+#pragma warning (disable : 4306 )
+/* conditional expression is constant: introduced by FD_SET(..) */
+#pragma warning (disable : 4127)
+/* non-constant aggregate initializer: issued due to missing C99 support */
+#pragma warning (disable : 4204)
+#endif
+
+/* Disable WIN32_LEAN_AND_MEAN.
+ This makes windows.h always include winsock2.h */
+#if defined(WIN32_LEAN_AND_MEAN)
+#undef WIN32_LEAN_AND_MEAN
+#endif
+
+#if defined USE_IPV6 && defined(_WIN32)
+#include <ws2tcpip.h>
+#endif
+
+#if defined(__SYMBIAN32__)
+#define NO_SSL /* SSL is not supported */
+#define NO_CGI /* CGI is not supported */
+#define PATH_MAX FILENAME_MAX
+#endif /* __SYMBIAN32__ */
+
+#ifndef IGNORE_UNUSED_RESULT
+#define IGNORE_UNUSED_RESULT(a) (void)((a) && 1)
+#endif
+
+#ifndef _WIN32_WCE /* Some ANSI #includes are not available on Windows CE */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#endif /* !_WIN32_WCE */
+
+#include <time.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#ifndef MAX_WORKER_THREADS
+#define MAX_WORKER_THREADS (1024*64)
+#endif
+
+#if defined(_WIN32) && !defined(__SYMBIAN32__) /* Windows specific */
+#if defined(_MSC_VER) && _MSC_VER <= 1400
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400 /* To make it link in VS2005 */
+#endif
+#include <windows.h>
+typedef const char * SOCK_OPT_TYPE;
+
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+
+#ifndef _IN_PORT_T
+#ifndef in_port_t
+#define in_port_t u_short
+#endif
+#endif
+
+#ifndef _WIN32_WCE
+#include <process.h>
+#include <direct.h>
+#include <io.h>
+#else /* _WIN32_WCE */
+#define NO_CGI /* WinCE has no pipes */
+
+typedef long off_t;
+
+#define errno GetLastError()
+#define strerror(x) _ultoa(x, (char *) _alloca(sizeof(x) *3 ), 10)
+#endif /* _WIN32_WCE */
+
+#define MAKEUQUAD(lo, hi) ((uint64_t)(((uint32_t)(lo)) | \
+ ((uint64_t)((uint32_t)(hi))) << 32))
+#define RATE_DIFF 10000000 /* 100 nsecs */
+#define EPOCH_DIFF MAKEUQUAD(0xd53e8000, 0x019db1de)
+#define SYS2UNIX_TIME(lo, hi) \
+ (time_t) ((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)
+
+/* Visual Studio 6 does not know __func__ or __FUNCTION__
+ The rest of MS compilers use __FUNCTION__, not C99 __func__
+ Also use _strtoui64 on modern M$ compilers */
+#if defined(_MSC_VER) && _MSC_VER < 1300
+#define STRX(x) #x
+#define STR(x) STRX(x)
+#define __func__ __FILE__ ":" STR(__LINE__)
+#define strtoull(x, y, z) (unsigned __int64) _atoi64(x)
+#define strtoll(x, y, z) _atoi64(x)
+#else
+#define __func__ __FUNCTION__
+#define strtoull(x, y, z) _strtoui64(x, y, z)
+#define strtoll(x, y, z) _strtoi64(x, y, z)
+#endif /* _MSC_VER */
+
+#define ERRNO GetLastError()
+#define NO_SOCKLEN_T
+#define SSL_LIB "ssleay32.dll"
+#define CRYPTO_LIB "libeay32.dll"
+#define O_NONBLOCK 0
+#define W_OK (2) /* http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx */
+#if !defined(EWOULDBLOCK)
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#endif /* !EWOULDBLOCK */
+#define _POSIX_
+#define INT64_FMT "I64d"
+
+#define WINCDECL __cdecl
+#define SHUT_WR 1
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#define access _access
+#define mg_sleep(x) Sleep(x)
+
+#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
+#ifndef popen
+#define popen(x, y) _popen(x, y)
+#endif
+#ifndef pclose
+#define pclose(x) _pclose(x)
+#endif
+#define close(x) _close(x)
+#define dlsym(x,y) GetProcAddress((HINSTANCE) (x), (y))
+#define RTLD_LAZY 0
+#define fseeko(x, y, z) _lseeki64(_fileno(x), (y), (z))
+#define fdopen(x, y) _fdopen((x), (y))
+#define write(x, y, z) _write((x), (y), (unsigned) z)
+#define read(x, y, z) _read((x), (y), (unsigned) z)
+#define flockfile(x) EnterCriticalSection(&global_log_file_lock)
+#define funlockfile(x) LeaveCriticalSection(&global_log_file_lock)
+#define sleep(x) Sleep((x) * 1000)
+#define rmdir(x) _rmdir(x)
+
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+#define USE_TIMERS
+#endif
+
+#if !defined(va_copy)
+#define va_copy(x, y) x = y
+#endif /* !va_copy MINGW #defines va_copy */
+
+#if !defined(fileno)
+#define fileno(x) _fileno(x)
+#endif /* !fileno MINGW #defines fileno */
+
+typedef HANDLE pthread_mutex_t;
+typedef DWORD pthread_key_t;
+typedef HANDLE pthread_t;
+typedef struct {
+ CRITICAL_SECTION threadIdSec;
+ int waitingthreadcount; /* The number of threads queued. */
+ pthread_t *waitingthreadhdls; /* The thread handles. */
+} pthread_cond_t;
+
+#ifndef __clockid_t_defined
+typedef DWORD clockid_t;
+#endif
+#ifndef CLOCK_MONOTONIC
+#define CLOCK_MONOTONIC (1)
+#endif
+#ifndef CLOCK_REALTIME
+#define CLOCK_REALTIME (2)
+#endif
+
+#ifndef _TIMESPEC_DEFINED
+struct timespec {
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+#endif
+
+#define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */
+
+static int pthread_mutex_lock(pthread_mutex_t *);
+static int pthread_mutex_unlock(pthread_mutex_t *);
+static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len);
+struct file;
+static char *mg_fgets(char *buf, size_t size, struct file *filep, char **p);
+
+#if defined(HAVE_STDINT)
+#include <stdint.h>
+#else
+typedef unsigned int uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned __int64 uint64_t;
+typedef __int64 int64_t;
+#define INT64_MAX 9223372036854775807
+#endif /* HAVE_STDINT */
+
+/* POSIX dirent interface */
+struct dirent {
+ char d_name[PATH_MAX];
+};
+
+typedef struct DIR {
+ HANDLE handle;
+ WIN32_FIND_DATAW info;
+ struct dirent result;
+} DIR;
+
+#if !defined(USE_IPV6) && defined(_WIN32)
+#ifndef HAVE_POLL
+struct pollfd {
+ SOCKET fd;
+ short events;
+ short revents;
+};
+#define POLLIN 1
+#endif
+#endif
+
+/* Mark required libraries */
+#ifdef _MSC_VER
+#pragma comment(lib, "Ws2_32.lib")
+#endif
+
+#else /* UNIX specific */
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <sys/utsname.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <netdb.h>
+typedef const void * SOCK_OPT_TYPE;
+
+//#if defined(ANDROID)
+typedef unsigned short int in_port_t;
+//#endif
+
+#include <pwd.h>
+#include <unistd.h>
+#include <dirent.h>
+#if !defined(NO_SSL_DL) && !defined(NO_SSL)
+#include <dlfcn.h>
+#endif
+#include <pthread.h>
+#if defined(__MACH__)
+#define SSL_LIB "libssl.dylib"
+#define CRYPTO_LIB "libcrypto.dylib"
+#else
+#if !defined(SSL_LIB)
+#define SSL_LIB "libssl.so"
+#endif
+#if !defined(CRYPTO_LIB)
+#define CRYPTO_LIB "libcrypto.so"
+#endif
+#endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif /* O_BINARY */
+#define closesocket(a) close(a)
+#define mg_mkdir(x, y) mkdir(x, y)
+#define mg_remove(x) remove(x)
+#define mg_sleep(x) usleep((x) * 1000)
+#define ERRNO errno
+#define INVALID_SOCKET (-1)
+#define INT64_FMT PRId64
+typedef int SOCKET;
+#define WINCDECL
+
+#endif /* End of Windows and UNIX specific includes */
+
+#ifdef _WIN32
+static CRITICAL_SECTION global_log_file_lock;
+static DWORD pthread_self(void)
+{
+ return GetCurrentThreadId();
+}
+
+int pthread_key_create(pthread_key_t *key, void (*_must_be_zero)(void*) /* destructor function not supported for windows */)
+{
+ assert(_must_be_zero == NULL);
+ if ((key!=0) && (_must_be_zero == NULL)) {
+ *key = TlsAlloc();
+ return (*key != TLS_OUT_OF_INDEXES) ? 0 : -1;
+ }
+ return -2;
+}
+
+int pthread_key_delete(pthread_key_t key)
+{
+ return TlsFree(key) ? 0 : 1;
+}
+
+int pthread_setspecific(pthread_key_t key, void * value)
+{
+ return TlsSetValue(key, value) ? 0 : 1;
+}
+
+void *pthread_getspecific(pthread_key_t key)
+{
+ return TlsGetValue(key);
+}
+#endif /* _WIN32 */
+
+
+#include "civetweb.h"
+
+#define PASSWORDS_FILE_NAME ".htpasswd"
+#define CGI_ENVIRONMENT_SIZE 4096
+#define MAX_CGI_ENVIR_VARS 64
+#define MG_BUF_LEN 8192
+#ifndef MAX_REQUEST_SIZE
+#define MAX_REQUEST_SIZE 16384
+#endif
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+
+#if !defined(DEBUG_TRACE)
+#if defined(CWDEBUG)
+
+static void DEBUG_TRACE_FUNC(const char *func, unsigned line, PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(3, 4);
+
+static void DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...) {
+
+ va_list args;
+ flockfile(stdout);
+ printf("*** %lu.%p.%s.%u: ",
+ (unsigned long) time(NULL), (void *) pthread_self(),
+ func, line);
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+ putchar('\n');
+ fflush(stdout);
+ funlockfile(stdout);
+}
+
+#define DEBUG_TRACE(fmt, ...) DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__)
+
+#else
+#define DEBUG_TRACE(fmt, ...)
+#endif /* CWDEBUG */
+#endif /* DEBUG_TRACE */
+
+#if defined(MEMORY_DEBUGGING)
+static unsigned long blockCount = 0;
+static unsigned long totalMemUsed = 0;
+
+static void * mg_malloc_ex(size_t size, const char * file, unsigned line) {
+
+ void * data = malloc(size + sizeof(size_t));
+ void * memory = 0;
+ char mallocStr[256];
+
+ if (data) {
+ *(size_t*)data = size;
+ totalMemUsed += size;
+ blockCount++;
+ memory = (void *)(((char*)data)+sizeof(size_t));
+ }
+
+ sprintf(mallocStr, "MEM: %p %5lu alloc %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+ OutputDebugStringA(mallocStr);
+#else
+ DEBUG_TRACE("%s", mallocStr);
+#endif
+
+ return memory;
+}
+
+static void * mg_calloc_ex(size_t count, size_t size, const char * file, unsigned line) {
+
+ void * data = mg_malloc_ex(size*count, file, line);
+ if (data) memset(data, 0, size);
+
+ return data;
+}
+
+static void mg_free_ex(void * memory, const char * file, unsigned line) {
+
+ char mallocStr[256];
+ void * data = (void *)(((char*)memory)-sizeof(size_t));
+ size_t size;
+
+ if (memory) {
+ size = *(size_t*)data;
+ totalMemUsed -= size;
+ blockCount--;
+ sprintf(mallocStr, "MEM: %p %5lu free %7lu %4lu --- %s:%u\n", memory, (unsigned long)size, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+ OutputDebugStringA(mallocStr);
+#else
+ DEBUG_TRACE("%s", mallocStr);
+#endif
+
+ free(data);
+ }
+}
+
+static void * mg_realloc_ex(void * memory, size_t newsize, const char * file, unsigned line) {
+
+ char mallocStr[256];
+ void * data;
+ void * _realloc;
+ size_t oldsize;
+
+ if (newsize) {
+ if (memory) {
+ data = (void *)(((char*)memory)-sizeof(size_t));
+ oldsize = *(size_t*)data;
+ _realloc = realloc(data, newsize+sizeof(size_t));
+ if (_realloc) {
+ data = _realloc;
+ totalMemUsed -= oldsize;
+ sprintf(mallocStr, "MEM: %p %5lu r-free %7lu %4lu --- %s:%u\n", memory, (unsigned long)oldsize, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+ OutputDebugStringA(mallocStr);
+#else
+ DEBUG_TRACE("%s", mallocStr);
+#endif
+ totalMemUsed += newsize;
+ sprintf(mallocStr, "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n", memory, (unsigned long)newsize, totalMemUsed, blockCount, file, line);
+#if defined(_WIN32)
+ OutputDebugStringA(mallocStr);
+#else
+ DEBUG_TRACE("%s", mallocStr);
+#endif
+ *(size_t*)data = newsize;
+ data = (void *)(((char*)data)+sizeof(size_t));
+ } else {
+#if defined(_WIN32)
+ OutputDebugStringA("MEM: realloc failed\n");
+#else
+ DEBUG_TRACE("%s", "MEM: realloc failed\n");
+#endif
+ return _realloc;
+ }
+ } else {
+ data = mg_malloc_ex(newsize, file, line);
+ }
+ } else {
+ data = 0;
+ mg_free_ex(memory, file, line);
+ }
+
+ return data;
+}
+
+#define mg_malloc(a) mg_malloc_ex(a, __FILE__, __LINE__)
+#define mg_calloc(a,b) mg_calloc_ex(a, b, __FILE__, __LINE__)
+#define mg_realloc(a, b) mg_realloc_ex(a, b, __FILE__, __LINE__)
+#define mg_free(a) mg_free_ex(a, __FILE__, __LINE__)
+
+#else
+static __inline void * mg_malloc(size_t a) {return malloc(a);}
+static __inline void * mg_calloc(size_t a, size_t b) {return calloc(a, b);}
+static __inline void * mg_realloc(void * a, size_t b) {return realloc(a, b);}
+static __inline void mg_free(void * a) {free(a);}
+#endif
+
+/* This following lines are just meant as a reminder to use the mg-functions for memory management */
+#ifdef malloc
+ #undef malloc
+#endif
+#ifdef calloc
+ #undef calloc
+#endif
+#ifdef realloc
+ #undef realloc
+#endif
+#ifdef free
+ #undef free
+#endif
+#define malloc DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc
+#define calloc DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc
+#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc
+#define free DO_NOT_USE_THIS_FUNCTION__USE_mg_free
+
+
+#define MD5_STATIC static
+#include "md5.inl"
+
+/* Darwin prior to 7.0 and Win32 do not have socklen_t */
+#ifdef NO_SOCKLEN_T
+typedef int socklen_t;
+#endif /* NO_SOCKLEN_T */
+#define _DARWIN_UNLIMITED_SELECT
+
+#define IP_ADDR_STR_LEN 50 /* IPv6 hex string is 46 chars */
+
+#if !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
+#if !defined(SOMAXCONN)
+#define SOMAXCONN 100
+#endif
+
+#if !defined(PATH_MAX)
+#define PATH_MAX 4096
+#endif
+
+/* Size of the accepted socket queue */
+#if !defined(MGSQLEN)
+#define MGSQLEN 20
+#endif
+
+#if defined(NO_SSL_DL)
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#else
+/* SSL loaded dynamically from DLL.
+ I put the prototypes here to be independent from OpenSSL source
+ installation. */
+
+typedef struct ssl_st SSL;
+typedef struct ssl_method_st SSL_METHOD;
+typedef struct ssl_ctx_st SSL_CTX;
+
+struct ssl_func {
+ const char *name; /* SSL function name */
+ void (*ptr)(void); /* Function pointer */
+};
+
+#define SSL_free (* (void (*)(SSL *)) ssl_sw[0].ptr)
+#define SSL_accept (* (int (*)(SSL *)) ssl_sw[1].ptr)
+#define SSL_connect (* (int (*)(SSL *)) ssl_sw[2].ptr)
+#define SSL_read (* (int (*)(SSL *, void *, int)) ssl_sw[3].ptr)
+#define SSL_write (* (int (*)(SSL *, const void *,int)) ssl_sw[4].ptr)
+#define SSL_get_error (* (int (*)(SSL *, int)) ssl_sw[5].ptr)
+#define SSL_set_fd (* (int (*)(SSL *, SOCKET)) ssl_sw[6].ptr)
+#define SSL_new (* (SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
+#define SSL_CTX_new (* (SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
+#define SSLv23_server_method (* (SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
+#define SSL_library_init (* (int (*)(void)) ssl_sw[10].ptr)
+#define SSL_CTX_use_PrivateKey_file (* (int (*)(SSL_CTX *, \
+ const char *, int)) ssl_sw[11].ptr)
+#define SSL_CTX_use_certificate_file (* (int (*)(SSL_CTX *, \
+ const char *, int)) ssl_sw[12].ptr)
+#define SSL_CTX_set_default_passwd_cb \
+ (* (void (*)(SSL_CTX *, mg_callback_t)) ssl_sw[13].ptr)
+#define SSL_CTX_free (* (void (*)(SSL_CTX *)) ssl_sw[14].ptr)
+#define SSL_load_error_strings (* (void (*)(void)) ssl_sw[15].ptr)
+#define SSL_CTX_use_certificate_chain_file \
+ (* (int (*)(SSL_CTX *, const char *)) ssl_sw[16].ptr)
+#define SSLv23_client_method (* (SSL_METHOD * (*)(void)) ssl_sw[17].ptr)
+#define SSL_pending (* (int (*)(SSL *)) ssl_sw[18].ptr)
+#define SSL_CTX_set_verify (* (void (*)(SSL_CTX *, int, int)) ssl_sw[19].ptr)
+#define SSL_shutdown (* (int (*)(SSL *)) ssl_sw[20].ptr)
+
+#define CRYPTO_num_locks (* (int (*)(void)) crypto_sw[0].ptr)
+#define CRYPTO_set_locking_callback \
+ (* (void (*)(void (*)(int, int, const char *, int))) crypto_sw[1].ptr)
+#define CRYPTO_set_id_callback \
+ (* (void (*)(unsigned long (*)(void))) crypto_sw[2].ptr)
+#define ERR_get_error (* (unsigned long (*)(void)) crypto_sw[3].ptr)
+#define ERR_error_string (* (char * (*)(unsigned long,char *)) crypto_sw[4].ptr)
+
+/* set_ssl_option() function updates this array.
+ It loads SSL library dynamically and changes NULLs to the actual addresses
+ of respective functions. The macros above (like SSL_connect()) are really
+ just calling these functions indirectly via the pointer. */
+static struct ssl_func ssl_sw[] = {
+ {"SSL_free", NULL},
+ {"SSL_accept", NULL},
+ {"SSL_connect", NULL},
+ {"SSL_read", NULL},
+ {"SSL_write", NULL},
+ {"SSL_get_error", NULL},
+ {"SSL_set_fd", NULL},
+ {"SSL_new", NULL},
+ {"SSL_CTX_new", NULL},
+ {"SSLv23_server_method", NULL},
+ {"SSL_library_init", NULL},
+ {"SSL_CTX_use_PrivateKey_file", NULL},
+ {"SSL_CTX_use_certificate_file",NULL},
+ {"SSL_CTX_set_default_passwd_cb",NULL},
+ {"SSL_CTX_free", NULL},
+ {"SSL_load_error_strings", NULL},
+ {"SSL_CTX_use_certificate_chain_file", NULL},
+ {"SSLv23_client_method", NULL},
+ {"SSL_pending", NULL},
+ {"SSL_CTX_set_verify", NULL},
+ {"SSL_shutdown", NULL},
+ {NULL, NULL}
+};
+
+/* Similar array as ssl_sw. These functions could be located in different
+ lib. */
+#if !defined(NO_SSL)
+static struct ssl_func crypto_sw[] = {
+ {"CRYPTO_num_locks", NULL},
+ {"CRYPTO_set_locking_callback", NULL},
+ {"CRYPTO_set_id_callback", NULL},
+ {"ERR_get_error", NULL},
+ {"ERR_error_string", NULL},
+ {NULL, NULL}
+};
+#endif /* NO_SSL */
+#endif /* NO_SSL_DL */
+
+static const char *month_names[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+/* Unified socket address. For IPv6 support, add IPv6 address structure
+ in the union u. */
+union usa {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+#if defined(USE_IPV6)
+ struct sockaddr_in6 sin6;
+#endif
+};
+
+/* Describes a string (chunk of memory). */
+struct vec {
+ const char *ptr;
+ size_t len;
+};
+
+struct file {
+ int is_directory;
+ time_t modification_time;
+ int64_t size;
+ FILE *fp;
+ const char *membuf; /* Non-NULL if file data is in memory */
+ /* set to 1 if the content is gzipped
+ in which case we need a content-encoding: gzip header */
+ int gzipped;
+};
+#define STRUCT_FILE_INITIALIZER {0, 0, 0, NULL, NULL, 0}
+
+/* Describes listening socket, or socket which was accept()-ed by the master
+ thread and queued for future handling by the worker thread. */
+struct socket {
+ SOCKET sock; /* Listening socket */
+ union usa lsa; /* Local socket address */
+ union usa rsa; /* Remote socket address */
+ unsigned is_ssl:1; /* Is port SSL-ed */
+ unsigned ssl_redir:1; /* Is port supposed to redirect everything to SSL
+ port */
+};
+
+/* NOTE(lsm): this enum shoulds be in sync with the config_options below. */
+enum {
+ CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER,
+ PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS, THROTTLE,
+ ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE,
+ GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
+ EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE,
+ NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT,
+ DECODE_URL,
+
+#if defined(USE_LUA)
+ LUA_PRELOAD_FILE, LUA_SCRIPT_EXTENSIONS, LUA_SERVER_PAGE_EXTENSIONS,
+#endif
+#if defined(USE_WEBSOCKET)
+ WEBSOCKET_ROOT,
+#endif
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+ LUA_WEBSOCKET_EXTENSIONS,
+#endif
+ ACCESS_CONTROL_ALLOW_ORIGIN, ERROR_PAGES,
+
+ NUM_OPTIONS
+};
+
+/* Config option name, config types, default value */
+static struct mg_option config_options[] = {
+ {"cgi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.cgi$|**.pl$|**.php$"},
+ {"cgi_environment", CONFIG_TYPE_STRING, NULL},
+ {"put_delete_auth_file", CONFIG_TYPE_FILE, NULL},
+ {"cgi_interpreter", CONFIG_TYPE_FILE, NULL},
+ {"protect_uri", CONFIG_TYPE_STRING, NULL},
+ {"authentication_domain", CONFIG_TYPE_STRING, "mydomain.com"},
+ {"ssi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.shtml$|**.shtm$"},
+ {"throttle", CONFIG_TYPE_STRING, NULL},
+ {"access_log_file", CONFIG_TYPE_FILE, NULL},
+ {"enable_directory_listing", CONFIG_TYPE_BOOLEAN, "yes"},
+ {"error_log_file", CONFIG_TYPE_FILE, NULL},
+ {"global_auth_file", CONFIG_TYPE_FILE, NULL},
+ {"index_files", CONFIG_TYPE_STRING,
+#ifdef USE_LUA
+ "index.xhtml,index.html,index.htm,index.lp,index.lsp,index.lua,index.cgi,index.shtml,index.php"},
+#else
+ "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
+#endif
+ {"enable_keep_alive", CONFIG_TYPE_BOOLEAN, "no"},
+ {"access_control_list", CONFIG_TYPE_STRING, NULL},
+ {"extra_mime_types", CONFIG_TYPE_STRING, NULL},
+ {"listening_ports", CONFIG_TYPE_STRING, "8080"},
+ {"document_root", CONFIG_TYPE_DIRECTORY, NULL},
+ {"ssl_certificate", CONFIG_TYPE_FILE, NULL},
+ {"num_threads", CONFIG_TYPE_NUMBER, "50"},
+ {"run_as_user", CONFIG_TYPE_STRING, NULL},
+ {"url_rewrite_patterns", CONFIG_TYPE_STRING, NULL},
+ {"hide_files_patterns", CONFIG_TYPE_EXT_PATTERN, NULL},
+ {"request_timeout_ms", CONFIG_TYPE_NUMBER, "30000"},
+ {"decode_url", CONFIG_TYPE_BOOLEAN, "yes"},
+
+#if defined(USE_LUA)
+ {"lua_preload_file", CONFIG_TYPE_FILE, NULL},
+ {"lua_script_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
+ {"lua_server_page_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lp$|**.lsp$"},
+#endif
+#if defined(USE_WEBSOCKET)
+ {"websocket_root", CONFIG_TYPE_DIRECTORY, NULL},
+#endif
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+ {"lua_websocket_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
+#endif
+ {"access_control_allow_origin", CONFIG_TYPE_STRING, "*"},
+ {"error_pages", CONFIG_TYPE_DIRECTORY, NULL},
+
+ {NULL, CONFIG_TYPE_UNKNOWN, NULL}
+};
+
+struct mg_request_handler_info {
+ char *uri;
+ size_t uri_len;
+ mg_request_handler handler;
+
+ void *cbdata;
+ struct mg_request_handler_info *next;
+};
+
+struct mg_context {
+ volatile int stop_flag; /* Should we stop event loop */
+ SSL_CTX *ssl_ctx; /* SSL context */
+ char *config[NUM_OPTIONS]; /* Civetweb configuration parameters */
+ struct mg_callbacks callbacks; /* User-defined callback function */
+ void *user_data; /* User-defined data */
+ int context_type; /* 1 = server context, 2 = client context */
+
+ struct socket *listening_sockets;
+ in_port_t *listening_ports;
+ int num_listening_sockets;
+
+ volatile int num_threads; /* Number of threads */
+ pthread_mutex_t thread_mutex; /* Protects (max|num)_threads */
+ pthread_cond_t thread_cond; /* Condvar for tracking workers terminations */
+
+ struct socket queue[MGSQLEN]; /* Accepted sockets */
+ volatile int sq_head; /* Head of the socket queue */
+ volatile int sq_tail; /* Tail of the socket queue */
+ pthread_cond_t sq_full; /* Signaled when socket is produced */
+ pthread_cond_t sq_empty; /* Signaled when socket is consumed */
+ pthread_t masterthreadid; /* The master thread ID */
+ int workerthreadcount; /* The amount of worker threads. */
+ pthread_t *workerthreadids; /* The worker thread IDs */
+
+ unsigned long start_time; /* Server start time, used for authentication */
+ pthread_mutex_t nonce_mutex; /* Protects nonce_count */
+ unsigned long nonce_count; /* Used nonces, used for authentication */
+
+ char *systemName; /* What operating system is running */
+
+ /* linked list of uri handlers */
+ struct mg_request_handler_info *request_handlers;
+
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+ /* linked list of shared lua websockets */
+ struct mg_shared_lua_websocket_list *shared_lua_websockets;
+#endif
+
+#ifdef USE_TIMERS
+ struct ttimers * timers;
+#endif
+};
+
+struct mg_connection {
+ struct mg_request_info request_info;
+ struct mg_context *ctx;
+ SSL *ssl; /* SSL descriptor */
+ SSL_CTX *client_ssl_ctx; /* SSL context for client connections */
+ struct socket client; /* Connected client */
+ time_t birth_time; /* Time when request was received */
+ int64_t num_bytes_sent; /* Total bytes sent to client */
+ int64_t content_len; /* Content-Length header value */
+ int64_t consumed_content; /* How many bytes of content have been read */
+ char *buf; /* Buffer for received data */
+ char *path_info; /* PATH_INFO part of the URL */
+ int must_close; /* 1 if connection must be closed */
+ int in_error_handler; /* 1 if in handler for user defined error pages */
+ int buf_size; /* Buffer size */
+ int request_len; /* Size of the request + headers in a buffer */
+ int data_len; /* Total size of data in a buffer */
+ int status_code; /* HTTP reply status code, e.g. 200 */
+ int throttle; /* Throttling, bytes/sec. <= 0 means no throttle */
+ time_t last_throttle_time; /* Last time throttled data was sent */
+ int64_t last_throttle_bytes; /* Bytes sent this second */
+ pthread_mutex_t mutex; /* Used by mg_lock_connection/mg_unlock_connection to ensure atomic transmissions for websockets */
+#if defined(USE_LUA) && defined(USE_WEBSOCKET)
+ void * lua_websocket_state; /* Lua_State for a websocket connection */
+#endif
+};
+
+static pthread_key_t sTlsKey; /* Thread local storage index */
+static int sTlsInit = 0;
+
+struct mg_workerTLS {
+ int is_master;
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+ HANDLE pthread_cond_helper_mutex;
+#endif
+};
+
+/* Directory entry */
+struct de {
+ struct mg_connection *conn;
+ char *file_name;
+ struct file file;
+};
+
+#if defined(USE_WEBSOCKET)
+static int is_websocket_protocol(const struct mg_connection *conn);
+#else
+#define is_websocket_protocol(conn) (0)
+#endif
+
+int mg_atomic_inc(volatile int * addr)
+{
+ int ret;
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+ ret = InterlockedIncrement((volatile unsigned int *) addr);
+#elif defined(__GNUC__)
+ ret = __sync_add_and_fetch(addr, 1);
+#else
+ ret = (++(*addr));
+#endif
+ return ret;
+}
+
+int mg_atomic_dec(volatile int * addr)
+{
+ int ret;
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+ ret = InterlockedDecrement((volatile unsigned int *) addr);
+#elif defined(__GNUC__)
+ ret = __sync_sub_and_fetch(addr, 1);
+#else
+ ret = (--(*addr));
+#endif
+ return ret;
+}
+
+#if !defined(NO_THREAD_NAME)
+#if defined(_WIN32) && defined(_MSC_VER)
+/* Set the thread name for debugging purposes in Visual Studio
+ http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
+*/
+#pragma pack(push,8)
+typedef struct tagTHREADNAME_INFO
+{
+ DWORD dwType; /* Must be 0x1000. */
+ LPCSTR szName; /* Pointer to name (in user addr space). */
+ DWORD dwThreadID; /* Thread ID (-1=caller thread). */
+ DWORD dwFlags; /* Reserved for future use, must be zero. */
+} THREADNAME_INFO;
+#pragma pack(pop)
+#elif defined(__linux__)
+#include <sys/prctl.h>
+#endif
+
+void mg_set_thread_name(const char* name)
+{
+ char threadName[16]; /* Max. thread length in Linux/OSX/.. */
+
+ if (snprintf(threadName, sizeof(threadName), "civetweb-%s", name)<0) return;
+ threadName[sizeof(threadName)-1] = 0;
+
+#if defined(_WIN32)
+#if defined(_MSC_VER)
+ /* Windows and Visual Studio Compiler */
+ __try
+ {
+ THREADNAME_INFO info;
+ info.dwType = 0x1000;
+ info.szName = threadName;
+ info.dwThreadID = -1;
+ info.dwFlags = 0;
+
+ RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ }
+#elif defined(__MINGW32__)
+ /* No option known to set thread name for MinGW */
+#endif
+#elif defined(__linux__)
+ /* Linux */
+ (void)prctl(PR_SET_NAME,threadName,0,0,0);
+#elif defined(__APPLE__) || defined(__MACH__)
+ /* OS X (TODO: test) */
+ (void)pthread_setname_np(threadName);
+#elif defined(BSD) || defined(__FreeBSD__) || defined(__OpenBSD__)
+ /* BSD (TODO: test) */
+ pthread_set_name_np(pthread_self(), threadName);
+#else
+ /* POSIX */
+ (void)pthread_setname_np(pthread_self(), threadName);
+#endif
+}
+#else /* !defined(NO_THREAD_NAME) */
+void mg_set_thread_name(const char* threadName) {}
+#endif
+
+#if defined(MG_LEGACY_INTERFACE)
+const char **mg_get_valid_option_names(void)
+{
+ static const char * data[2 * sizeof(config_options) / sizeof(config_options[0])] = {0};
+ int i;
+
+ for (i=0; config_options[i].name != NULL; i++) {
+ data[i * 2] = config_options[i].name;
+ data[i * 2 + 1] = config_options[i].default_value;
+ }
+
+ return data;
+}
+#endif
+
+const struct mg_option *mg_get_valid_options(void)
+{
+ return config_options;
+}
+
+
+static int is_file_in_memory(struct mg_connection *conn, const char *path,
+ struct file *filep)
+{
+ size_t size = 0;
+ if ((filep->membuf = conn->ctx->callbacks.open_file == NULL ? NULL :
+ conn->ctx->callbacks.open_file(conn, path, &size)) != NULL) {
+ /* NOTE: override filep->size only on success. Otherwise, it might
+ break constructs like if (!mg_stat() || !mg_fopen()) ... */
+ filep->size = size;
+ }
+ return filep->membuf != NULL;
+}
+
+static int is_file_opened(const struct file *filep)
+{
+ return filep->membuf != NULL || filep->fp != NULL;
+}
+
+static int mg_fopen(struct mg_connection *conn, const char *path,
+ const char *mode, struct file *filep)
+{
+ if (!is_file_in_memory(conn, path, filep)) {
+#ifdef _WIN32
+ wchar_t wbuf[PATH_MAX], wmode[20];
+ to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
+ MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, ARRAY_SIZE(wmode));
+ filep->fp = _wfopen(wbuf, wmode);
+#else
+ filep->fp = fopen(path, mode);
+#endif
+ }
+
+ return is_file_opened(filep);
+}
+
+static void mg_fclose(struct file *filep)
+{
+ if (filep != NULL && filep->fp != NULL) {
+ fclose(filep->fp);
+ }
+}
+
+static void mg_strlcpy(register char *dst, register const char *src, size_t n)
+{
+ for (; *src != '\0' && n > 1; n--) {
+ *dst++ = *src++;
+ }
+ *dst = '\0';
+}
+
+static int lowercase(const char *s)
+{
+ return tolower(* (const unsigned char *) s);
+}
+
+int mg_strncasecmp(const char *s1, const char *s2, size_t len)
+{
+ int diff = 0;
+
+ if (len > 0)
+ do {
+ diff = lowercase(s1++) - lowercase(s2++);
+ } while (diff == 0 && s1[-1] != '\0' && --len > 0);
+
+ return diff;
+}
+
+static int mg_strcasecmp(const char *s1, const char *s2)
+{
+ int diff;
+
+ do {
+ diff = lowercase(s1++) - lowercase(s2++);
+ } while (diff == 0 && s1[-1] != '\0');
+
+ return diff;
+}
+
+static char * mg_strndup(const char *ptr, size_t len)
+{
+ char *p;
+
+ if ((p = (char *) mg_malloc(len + 1)) != NULL) {
+ mg_strlcpy(p, ptr, len + 1);
+ }
+
+ return p;
+}
+
+static char * mg_strdup(const char *str)
+{
+ return mg_strndup(str, strlen(str));
+}
+
+static const char *mg_strcasestr(const char *big_str, const char *small_str)
+{
+ int i, big_len = (int)strlen(big_str), small_len = (int)strlen(small_str);
+
+ for (i = 0; i <= big_len - small_len; i++) {
+ if (mg_strncasecmp(big_str + i, small_str, small_len) == 0) {
+ return big_str + i;
+ }
+ }
+
+ return NULL;
+}
+
+/* Like snprintf(), but never returns negative value, or a value
+ that is larger than a supplied buffer.
+ Thanks to Adam Zeldis to pointing snprintf()-caused vulnerability
+ in his audit report. */
+static int mg_vsnprintf(struct mg_connection *conn, char *buf, size_t buflen,
+ const char *fmt, va_list ap)
+{
+ int n;
+
+ if (buflen == 0)
+ return 0;
+
+ n = vsnprintf(buf, buflen, fmt, ap);
+
+ if (n < 0) {
+ mg_cry(conn, "vsnprintf error");
+ n = 0;
+ } else if (n >= (int) buflen) {
+ mg_cry(conn, "truncating vsnprintf buffer: [%.*s]",
+ n > 200 ? 200 : n, buf);
+ n = (int) buflen - 1;
+ }
+ buf[n] = '\0';
+
+ return n;
+}
+
+static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
+ PRINTF_FORMAT_STRING(const char *fmt), ...)
+PRINTF_ARGS(4, 5);
+
+static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
+ const char *fmt, ...)
+{
+ va_list ap;
+ int n;
+
+ va_start(ap, fmt);
+ n = mg_vsnprintf(conn, buf, buflen, fmt, ap);
+ va_end(ap);
+
+ return n;
+}
+
+static int get_option_index(const char *name)
+{
+ int i;
+
+ for (i = 0; config_options[i].name != NULL; i++) {
+ if (strcmp(config_options[i].name, name) == 0) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+const char *mg_get_option(const struct mg_context *ctx, const char *name)
+{
+ int i;
+ if ((i = get_option_index(name)) == -1) {
+ return NULL;
+ } else if (ctx->config[i] == NULL) {
+ return "";
+ } else {
+ return ctx->config[i];
+ }
+}
+
+struct mg_context *mg_get_context(struct mg_connection * conn)
+{
+ return (conn == NULL) ? (struct mg_context *)NULL : (conn->ctx);
+}
+
+void *mg_get_user_data(struct mg_context *ctx)
+{
+ return (ctx == NULL) ? NULL : ctx->user_data;
+}
+
+size_t mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl)
+{
+ size_t i;
+ for (i = 0; i < size && i < (size_t)ctx->num_listening_sockets; i++)
+ {
+ ssl[i] = ctx->listening_sockets[i].is_ssl;
+ ports[i] = ctx->listening_ports[i];
+ }
+ return i;
+}
+
+static void sockaddr_to_string(char *buf, size_t len,
+ const union usa *usa)
+{
+ buf[0] = '\0';
+#if defined(USE_IPV6)
+ inet_ntop(usa->sa.sa_family, usa->sa.sa_family == AF_INET ?
+ (void *) &usa->sin.sin_addr :
+ (void *) &usa->sin6.sin6_addr, buf, len);
+#elif defined(_WIN32)
+ /* Only Windows Vista (and newer) have inet_ntop() */
+ mg_strlcpy(buf, inet_ntoa(usa->sin.sin_addr), len);
+#else
+ inet_ntop(usa->sa.sa_family, (void *) &usa->sin.sin_addr, buf, len);
+#endif
+}
+
+/* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be included in all responses other than 100, 101, 5xx. */
+static void gmt_time_string(char *buf, size_t buf_len, time_t *t)
+{
+ struct tm *tm;
+
+ tm = gmtime(t);
+ if (tm != NULL) {
+ strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm);
+ } else {
+ mg_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
+ buf[buf_len - 1] = '\0';
+ }
+}
+
+/* Print error message to the opened error log stream. */
+void mg_cry(struct mg_connection *conn, const char *fmt, ...)
+{
+ char buf[MG_BUF_LEN], src_addr[IP_ADDR_STR_LEN];
+ va_list ap;
+ FILE *fp;
+ time_t timestamp;
+
+ va_start(ap, fmt);
+ IGNORE_UNUSED_RESULT(vsnprintf(buf, sizeof(buf), fmt, ap));
+ va_end(ap);
+
+ /* Do not lock when getting the callback value, here and below.
+ I suppose this is fine, since function cannot disappear in the
+ same way string option can. */
+ if (conn->ctx->callbacks.log_message == NULL ||
+ conn->ctx->callbacks.log_message(conn, buf) == 0) {
+ fp = conn->ctx->config[ERROR_LOG_FILE] == NULL ? NULL :
+ fopen(conn->ctx->config[ERROR_LOG_FILE], "a+");
+
+ if (fp != NULL) {
+ flockfile(fp);
+ timestamp = time(NULL);
+
+ sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
+ fprintf(fp, "[%010lu] [error] [client %s] ", (unsigned long) timestamp,
+ src_addr);
+
+ if (conn->request_info.request_method != NULL) {
+ fprintf(fp, "%s %s: ", conn->request_info.request_method,
+ conn->request_info.uri);
+ }
+
+ fprintf(fp, "%s", buf);
+ fputc('\n', fp);
+ funlockfile(fp);
+ fclose(fp);
+ }
+ }
+}
+
+/* Return fake connection structure. Used for logging, if connection
+ is not applicable at the moment of logging. */
+static struct mg_connection *fc(struct mg_context *ctx)
+{
+ static struct mg_connection fake_connection;
+ fake_connection.ctx = ctx;
+ return &fake_connection;
+}
+
+const char *mg_version(void)
+{
+ return CIVETWEB_VERSION;
+}
+
+struct mg_request_info *mg_get_request_info(struct mg_connection *conn)
+{
+ return &conn->request_info;
+}
+
+/* Skip the characters until one of the delimiters characters found.
+ 0-terminate resulting word. Skip the delimiter and following whitespaces.
+ Advance pointer to buffer to the next word. Return found 0-terminated word.
+ Delimiters can be quoted with quotechar. */
+static char *skip_quoted(char **buf, const char *delimiters,
+ const char *whitespace, char quotechar)
+{
+ char *p, *begin_word, *end_word, *end_whitespace;
+
+ begin_word = *buf;
+ end_word = begin_word + strcspn(begin_word, delimiters);
+
+ /* Check for quotechar */
+ if (end_word > begin_word) {
+ p = end_word - 1;
+ while (*p == quotechar) {
+ /* TODO (bel): it seems this code is never reached, so quotechar is actually
+ not needed - check if this code may be droped */
+
+ /* If there is anything beyond end_word, copy it */
+ if (*end_word == '\0') {
+ *p = '\0';
+ break;
+ } else {
+ size_t end_off = strcspn(end_word + 1, delimiters);
+ memmove (p, end_word, end_off + 1);
+ p += end_off; /* p must correspond to end_word - 1 */
+ end_word += end_off + 1;
+ }
+ }
+ for (p++; p < end_word; p++) {
+ *p = '\0';
+ }
+ }
+
+ if (*end_word == '\0') {
+ *buf = end_word;
+ } else {
+ end_whitespace = end_word + 1 + strspn(end_word + 1, whitespace);
+
+ for (p = end_word; p < end_whitespace; p++) {
+ *p = '\0';
+ }
+
+ *buf = end_whitespace;
+ }
+
+ return begin_word;
+}
+
+/* Simplified version of skip_quoted without quote char
+ and whitespace == delimiters */
+static char *skip(char **buf, const char *delimiters)
+{
+ return skip_quoted(buf, delimiters, delimiters, 0);
+}
+
+
+/* Return HTTP header value, or NULL if not found. */
+static const char *get_header(const struct mg_request_info *ri,
+ const char *name)
+{
+ int i;
+
+ for (i = 0; i < ri->num_headers; i++)
+ if (!mg_strcasecmp(name, ri->http_headers[i].name))
+ return ri->http_headers[i].value;
+
+ return NULL;
+}
+
+const char *mg_get_header(const struct mg_connection *conn, const char *name)
+{
+ return get_header(&conn->request_info, name);
+}
+
+/* A helper function for traversing a comma separated list of values.
+ It returns a list pointer shifted to the next value, or NULL if the end
+ of the list found.
+ Value is stored in val vector. If value has form "x=y", then eq_val
+ vector is initialized to point to the "y" part, and val vector length
+ is adjusted to point only to "x". */
+static const char *next_option(const char *list, struct vec *val,
+ struct vec *eq_val)
+{
+ if (list == NULL || *list == '\0') {
+ /* End of the list */
+ list = NULL;
+ } else {
+ val->ptr = list;
+ if ((list = strchr(val->ptr, ',')) != NULL) {
+ /* Comma found. Store length and shift the list ptr */
+ val->len = list - val->ptr;
+ list++;
+ } else {
+ /* This value is the last one */
+ list = val->ptr + strlen(val->ptr);
+ val->len = list - val->ptr;
+ }
+
+ if (eq_val != NULL) {
+ /* Value has form "x=y", adjust pointers and lengths
+ so that val points to "x", and eq_val points to "y". */
+ eq_val->len = 0;
+ eq_val->ptr = (const char *) memchr(val->ptr, '=', val->len);
+ if (eq_val->ptr != NULL) {
+ eq_val->ptr++; /* Skip over '=' character */
+ eq_val->len = val->ptr + val->len - eq_val->ptr;
+ val->len = (eq_val->ptr - val->ptr) - 1;
+ }
+ }
+ }
+
+ return list;
+}
+
+/* Perform case-insensitive match of string against pattern */
+static int match_prefix(const char *pattern, int pattern_len, const char *str)
+{
+ const char *or_str;
+ int i, j, len, res;
+
+ if ((or_str = (const char *) memchr(pattern, '|', pattern_len)) != NULL) {
+ res = match_prefix(pattern, (int)(or_str - pattern), str);
+ return res > 0 ? res :
+ match_prefix(or_str + 1, (int)((pattern + pattern_len) - (or_str + 1)), str);
+ }
+
+ i = j = 0;
+ for (; i < pattern_len; i++, j++) {
+ if (pattern[i] == '?' && str[j] != '\0') {
+ continue;
+ } else if (pattern[i] == '$') {
+ return str[j] == '\0' ? j : -1;
+ } else if (pattern[i] == '*') {
+ i++;
+ if (pattern[i] == '*') {
+ i++;
+ len = (int) strlen(str + j);
+ } else {
+ len = (int) strcspn(str + j, "/");
+ }
+ if (i == pattern_len) {
+ return j + len;
+ }
+ do {
+ res = match_prefix(pattern + i, pattern_len - i, str + j + len);
+ } while (res == -1 && len-- > 0);
+ return res == -1 ? -1 : j + res + len;
+ } else if (lowercase(&pattern[i]) != lowercase(&str[j])) {
+ return -1;
+ }
+ }
+ return j;
+}
+
+/* HTTP 1.1 assumes keep alive if "Connection:" header is not set
+ This function must tolerate situations when connection info is not
+ set up, for example if request parsing failed. */
+static int should_keep_alive(const struct mg_connection *conn)
+{
+ const char *http_version = conn->request_info.http_version;
+ const char *header = mg_get_header(conn, "Connection");
+ if (conn->must_close ||
+ conn->status_code == 401 ||
+ mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 ||
+ (header != NULL && mg_strcasecmp(header, "keep-alive") != 0) ||
+ (header == NULL && http_version && 0!=strcmp(http_version, "1.1"))) {
+ return 0;
+ }
+ return 1;
+}
+
+static int should_decode_url(const struct mg_connection *conn)
+{
+ return (mg_strcasecmp(conn->ctx->config[DECODE_URL], "yes") == 0);
+}
+
+static const char *suggest_connection_header(const struct mg_connection *conn)
+{
+ return should_keep_alive(conn) ? "keep-alive" : "close";
+}
+
+static void handle_file_based_request(struct mg_connection *conn, const char *path, struct file *filep);
+static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep);
+
+static const char *mg_get_response_code_text(int response_code, struct mg_connection *conn)
+{
+ switch (response_code)
+ {
+ /* RFC2616 Section 10.1 - Informational 1xx */
+ case 100: return "Continue"; /* RFC2616 Section 10.1.1 */
+ case 101: return "Switching Protocols"; /* RFC2616 Section 10.1.2 */
+ case 102: return "Processing"; /* RFC2518 Section 10.1 */
+
+ /* RFC2616 Section 10.2 - Successful 2xx */
+ case 200: return "OK"; /* RFC2616 Section 10.2.1 */
+ case 201: return "Created"; /* RFC2616 Section 10.2.2 */
+ case 202: return "Accepted"; /* RFC2616 Section 10.2.3 */
+ case 203: return "Non-Authoritative Information"; /* RFC2616 Section 10.2.4 */
+ case 204: return "No Content"; /* RFC2616 Section 10.2.5 */
+ case 205: return "Reset Content"; /* RFC2616 Section 10.2.6 */
+ case 206: return "Partial Content"; /* RFC2616 Section 10.2.7 */
+ case 207: return "Multi-Status"; /* RFC2518 Section 10.2, RFC4918 Section 11.1 */
+
+ /* RFC2616 Section 10.3 - Redirection 3xx */
+ case 300: return "Multiple Choices"; /* RFC2616 Section 10.3.1 */
+ case 301: return "Moved Permanently"; /* RFC2616 Section 10.3.2 */
+ case 302: return "Found"; /* RFC2616 Section 10.3.3 */
+ case 303: return "See Other"; /* RFC2616 Section 10.3.4 */
+ case 304: return "Not Modified"; /* RFC2616 Section 10.3.5 */
+ case 305: return "Use Proxy"; /* RFC2616 Section 10.3.6 */
+ case 307: return "Temporary Redirect"; /* RFC2616 Section 10.3.8 */
+
+ /* RFC2616 Section 10.4 - Client Error 4xx */
+ case 400: return "Bad Request"; /* RFC2616 Section 10.4.1 */
+ case 401: return "Unauthorized"; /* RFC2616 Section 10.4.2 */
+ case 402: return "Payment Required"; /* RFC2616 Section 10.4.3 */
+ case 403: return "Forbidden"; /* RFC2616 Section 10.4.4 */
+ case 404: return "Not Found"; /* RFC2616 Section 10.4.5 */
+ case 405: return "Method Not Allowed"; /* RFC2616 Section 10.4.6 */
+ case 406: return "Not Acceptable"; /* RFC2616 Section 10.4.7 */
+ case 407: return "Proxy Authentication Required"; /* RFC2616 Section 10.4.8 */
+ case 408: return "Request Time-out"; /* RFC2616 Section 10.4.9 */
+ case 409: return "Conflict"; /* RFC2616 Section 10.4.10 */
+ case 410: return "Gone"; /* RFC2616 Section 10.4.11 */
+ case 411: return "Length Required"; /* RFC2616 Section 10.4.12 */
+ case 412: return "Precondition Failed"; /* RFC2616 Section 10.4.13 */
+ case 413: return "Request Entity Too Large"; /* RFC2616 Section 10.4.14 */
+ case 414: return "Request-URI Too Large"; /* RFC2616 Section 10.4.15 */
+ case 415: return "Unsupported Media Type"; /* RFC2616 Section 10.4.16 */
+ case 416: return "Requested range not satisfiable"; /* RFC2616 Section 10.4.17 */
+ case 417: return "Expectation Failed"; /* RFC2616 Section 10.4.18 */
+ case 422: return "Unproccessable entity"; /* RFC2518 Section 10.3, RFC4918 Section 11.2 */
+ case 423: return "Locked"; /* RFC2518 Section 10.4, RFC4918 Section 11.3 */
+ case 424: return "Failed Dependency"; /* RFC2518 Section 10.5, RFC4918 Section 11.4 */
+ case 428: return "Precondition Required"; /* RFC 6585, Section 3 */
+ case 429: return "Too Many Requests"; /* RFC 6585, Section 4 */
+ case 431: return "Request Header Fields Too Large"; /* RFC 6585, Section 5 */
+
+ /* RFC2616 Section 10.5 - Server Error 5xx */
+ case 500: return "Internal Server Error"; /* RFC2616 Section 10.5.1 */
+ case 501: return "Not Implemented"; /* RFC2616 Section 10.5.2 */
+ case 502: return "Bad Gateway"; /* RFC2616 Section 10.5.3 */
+ case 503: return "Service Unavailable"; /* RFC2616 Section 10.5.4 */
+ case 504: return "Gateway Time-out"; /* RFC2616 Section 10.5.5 */
+ case 505: return "HTTP Version not supported"; /* RFC2616 Section 10.5.6 */
+ case 507: return "Insufficient Storage"; /* RFC2518 Section 10.6, , RFC4918 Section 11.5 */
+ case 511: return "Network Authentication Required"; /* RFC 6585, Section 6 */
+
+ /* Other RFCs */
+ case 426: return "Upgrade Required"; /* RFC 2817 */
+
+ /* Return codes from non normative RFCs: */
+ /* Informative and experimental RFCs, "de facto" standards due to common use, ... */
+ case 208: return "Already Reported"; /* RFC5842 Section 7.1 */
+ case 226: return "IM used"; /* RFC3229 Section 10.4.1 */
+ case 308: return "Permanent Redirect"; /* RFC7238 Section 3 */
+ case 418: return "I am a teapot"; /* RFC2324 Section 2.3.2 */
+ case 419: return "Authentication Timeout"; /* common use */
+ case 451: return "Unavailable For Legal Reasons"; /* draft-tbray-http-legally-restricted-status-05, Section 3 */
+ case 506: return "Variant Also Negotiates"; /* RFC 2295, Section 8.1 */
+ case 508: return "Loop Detected"; /* RFC5842 Section 7.1 */
+ case 510: return "Not Extended"; /* RFC 2774, Section 7 */
+
+ default:
+ /* This error code is unknown. This should not happen. */
+ if (conn) {
+ mg_cry(conn, "Unknown HTTP response code: %u", response_code);
+ }
+
+ /* Return at least a category according to RFC 2616 Section 10. */
+ if (response_code>=100 && response_code<200) {
+ /* Unknown informational status code */
+ return "Information";
+ }
+ if (response_code>=200 && response_code<300) {
+ /* Unknown success code */
+ return "Success";
+ }
+ if (response_code>=300 && response_code<400) {
+ /* Unknown redirection code */
+ return "Redirection";
+ }
+ if (response_code>=400 && response_code<500) {
+ /* Unknown request error code */
+ return "Client Error";
+ }
+ if (response_code>=500 && response_code<600) {
+ /* Unknown server error code */
+ return "Server Error";
+ }
+
+ /* Response code not even within reasonable range */
+ return "";
+ }
+}
+
+
+static void send_http_error(struct mg_connection *, int, const char *,
+ PRINTF_FORMAT_STRING(const char *fmt), ...)
+PRINTF_ARGS(4, 5);
+
+
+static void send_http_error(struct mg_connection *conn, int status,
+ const char *reason, const char *fmt, ...)
+{
+ char buf[MG_BUF_LEN];
+ va_list ap;
+ int len = 0, i, page_handler_found, scope;
+ char date[64];
+ time_t curtime = time(NULL);
+ const char *error_handler = NULL;
+ struct file error_page_file = STRUCT_FILE_INITIALIZER;
+ const char *error_page_file_ext, *tstr;
+
+ if (!reason) {
+ reason = mg_get_response_code_text(status, conn);
+ }
+
+ conn->status_code = status;
+ if (conn->in_error_handler ||
+ conn->ctx->callbacks.http_error == NULL ||
+ conn->ctx->callbacks.http_error(conn, status)) {
+
+ if (!conn->in_error_handler) {
+ /* Send user defined error pages, if defined */
+ error_handler = conn->ctx->config[ERROR_PAGES];
+ error_page_file_ext = conn->ctx->config[INDEX_FILES];
+ page_handler_found = 0;
+ if (error_handler != NULL) {
+ for (scope=1; (scope<=3) && !page_handler_found; scope++) {
+ switch (scope) {
+ case 1:
+ len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%03u.", error_handler, status);
+ break;
+ case 2:
+ len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror%01uxx.", error_handler, status/100);
+ break;
+ default:
+ len = mg_snprintf(conn, buf, sizeof(buf)-32, "%serror.", error_handler);
+ break;
+ }
+ tstr = strchr(error_page_file_ext, '.');
+ while (tstr) {
+ for (i=1; i<32 && tstr[i]!=0 && tstr[i]!=','; i++) buf[len+i-1]=tstr[i];
+ buf[len+i-1]=0;
+ if (mg_stat(conn, buf, &error_page_file)) {
+ page_handler_found = 1;
+ break;
+ }
+ tstr = strchr(tstr+i, '.');
+ }
+ }
+ }
+
+ if (page_handler_found) {
+ conn->in_error_handler = 1;
+ handle_file_based_request(conn, buf, &error_page_file);
+ conn->in_error_handler = 0;
+ return;
+ }
+ }
+
+ buf[0] = '\0';
+ gmt_time_string(date, sizeof(date), &curtime);
+
+ /* Errors 1xx, 204 and 304 MUST NOT send a body */
+ if (status > 199 && status != 204 && status != 304) {
+ len = mg_snprintf(conn, buf, sizeof(buf)-1, "Error %d: %s", status, reason);
+ buf[len] = '\n';
+ len++;
+ buf[len] = 0;
+
+ va_start(ap, fmt);
+ len += mg_vsnprintf(conn, buf + len, sizeof(buf) - len, fmt, ap);
+ va_end(ap);
+ }
+ DEBUG_TRACE("[%s]", buf);
+
+ mg_printf(conn, "HTTP/1.1 %d %s\r\n"
+ "Content-Length: %d\r\n"
+ "Date: %s\r\n"
+ "Connection: %s\r\n\r\n",
+ status, reason, len, date,
+ suggest_connection_header(conn));
+ conn->num_bytes_sent += mg_printf(conn, "%s", buf);
+ }
+}
+
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+static int pthread_mutex_init(pthread_mutex_t *mutex, void *unused)
+{
+ (void) unused;
+ *mutex = CreateMutex(NULL, FALSE, NULL);
+ return *mutex == NULL ? -1 : 0;
+}
+
+static int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+ return CloseHandle(*mutex) == 0 ? -1 : 0;
+}
+
+static int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+ return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1;
+}
+
+static int pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+ switch (WaitForSingleObject(*mutex, 0)) {
+ case WAIT_OBJECT_0:
+ return 0;
+ case WAIT_TIMEOUT:
+ return -2; /* EBUSY */
+ }
+ return -1;
+}
+
+static int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+ return ReleaseMutex(*mutex) == 0 ? -1 : 0;
+}
+
+#ifndef WIN_PTHREADS_TIME_H
+static int clock_gettime(clockid_t clk_id, struct timespec *tp)
+{
+ FILETIME ft;
+ ULARGE_INTEGER li;
+ BOOL ok = FALSE;
+ double d;
+ static double perfcnt_per_sec = 0.0;
+
+ if (tp) {
+ if (clk_id == CLOCK_REALTIME) {
+ GetSystemTimeAsFileTime(&ft);
+ li.LowPart = ft.dwLowDateTime;
+ li.HighPart = ft.dwHighDateTime;
+ li.QuadPart -= 116444736000000000; /* 1.1.1970 in filedate */
+ tp->tv_sec = (time_t)(li.QuadPart / 10000000);
+ tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
+ ok = TRUE;
+ } else if (clk_id == CLOCK_MONOTONIC) {
+ if (perfcnt_per_sec == 0.0) {
+ QueryPerformanceFrequency((LARGE_INTEGER *) &li);
+ perfcnt_per_sec = 1.0 / li.QuadPart;
+ }
+ if (perfcnt_per_sec != 0.0) {
+ QueryPerformanceCounter((LARGE_INTEGER *) &li);
+ d = li.QuadPart * perfcnt_per_sec;
+ tp->tv_sec = (time_t)d;
+ d -= tp->tv_sec;
+ tp->tv_nsec = (long)(d*1.0E9);
+ ok = TRUE;
+ }
+ }
+ }
+
+ return ok ? 0 : -1;
+}
+#endif
+
+static int pthread_cond_init(pthread_cond_t *cv, const void *unused)
+{
+ (void) unused;
+ InitializeCriticalSection(&cv->threadIdSec);
+ cv->waitingthreadcount = 0;
+ cv->waitingthreadhdls = (pthread_t *) mg_calloc(MAX_WORKER_THREADS, sizeof(pthread_t));
+ return (cv->waitingthreadhdls!=NULL) ? 0 : -1;
+}
+
+static int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mutex, const struct timespec * abstime)
+{
+ struct mg_workerTLS * tls = (struct mg_workerTLS *)TlsGetValue(sTlsKey);
+ int ok;
+ struct timespec tsnow;
+ int64_t nsnow, nswaitabs, nswaitrel;
+ DWORD mswaitrel;
+
+ EnterCriticalSection(&cv->threadIdSec);
+ assert(cv->waitingthreadcount < MAX_WORKER_THREADS);
+ cv->waitingthreadhdls[cv->waitingthreadcount] = tls->pthread_cond_helper_mutex;
+ cv->waitingthreadcount++;
+ LeaveCriticalSection(&cv->threadIdSec);
+
+ if (abstime) {
+ clock_gettime(CLOCK_REALTIME, &tsnow);
+ nsnow = (((uint64_t)tsnow.tv_sec)*1000000000) + tsnow.tv_nsec;
+ nswaitabs = (((uint64_t)abstime->tv_sec)*1000000000) + abstime->tv_nsec;
+ nswaitrel = nswaitabs - nsnow;
+ if (nswaitrel<0) nswaitrel=0;
+ mswaitrel = (DWORD)(nswaitrel / 1000000);
+ } else {
+ mswaitrel = INFINITE;
+ }
+
+ pthread_mutex_unlock(mutex);
+ ok = (WAIT_OBJECT_0 == WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel));
+ pthread_mutex_lock(mutex);
+
+ return ok ? 0 : -1;
+}
+
+static int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex)
+{
+ return pthread_cond_timedwait(cv, mutex, NULL);
+}
+
+static int pthread_cond_signal(pthread_cond_t *cv)
+{
+ int i;
+ HANDLE wkup = NULL;
+ BOOL ok = FALSE;
+
+ EnterCriticalSection(&cv->threadIdSec);
+ if (cv->waitingthreadcount) {
+ wkup = cv->waitingthreadhdls[0];
+ ok = SetEvent(wkup);
+
+ for (i=1; i<cv->waitingthreadcount; i++) {
+ cv->waitingthreadhdls[i-1] = cv->waitingthreadhdls[i];
+ }
+ cv->waitingthreadcount--;
+
+ assert(ok);
+ }
+ LeaveCriticalSection(&cv->threadIdSec);
+
+ return ok ? 0 : 1;
+}
+
+static int pthread_cond_broadcast(pthread_cond_t *cv)
+{
+ EnterCriticalSection(&cv->threadIdSec);
+ while (cv->waitingthreadcount) {
+ pthread_cond_signal(cv);
+ }
+ LeaveCriticalSection(&cv->threadIdSec);
+
+ return 0;
+}
+
+static int pthread_cond_destroy(pthread_cond_t *cv)
+{
+ EnterCriticalSection(&cv->threadIdSec);
+ assert(cv->waitingthreadcount==0);
+ mg_free(cv->waitingthreadhdls);
+ cv->waitingthreadhdls = 0;
+ LeaveCriticalSection(&cv->threadIdSec);
+ DeleteCriticalSection(&cv->threadIdSec);
+
+ return 0;
+}
+
+/* For Windows, change all slashes to backslashes in path names. */
+static void change_slashes_to_backslashes(char *path)
+{
+ int i;
+
+ for (i = 0; path[i] != '\0'; i++) {
+ if (path[i] == '/')
+ path[i] = '\\';
+ /* i > 0 check is to preserve UNC paths, like \\server\file.txt */
+ if (path[i] == '\\' && i > 0)
+ while (path[i + 1] == '\\' || path[i + 1] == '/')
+ (void) memmove(path + i + 1,
+ path + i + 2, strlen(path + i + 1));
+ }
+}
+
+/* Encode 'path' which is assumed UTF-8 string, into UNICODE string.
+ wbuf and wbuf_len is a target buffer and its length. */
+static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len)
+{
+ char buf[PATH_MAX], buf2[PATH_MAX];
+
+ mg_strlcpy(buf, path, sizeof(buf));
+ change_slashes_to_backslashes(buf);
+
+ /* Convert to Unicode and back. If doubly-converted string does not
+ match the original, something is fishy, reject. */
+ memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
+ MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
+ WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
+ NULL, NULL);
+ if (strcmp(buf, buf2) != 0) {
+ wbuf[0] = L'\0';
+ }
+}
+
+#if defined(_WIN32_WCE)
+static time_t time(time_t *ptime)
+{
+ time_t t;
+ SYSTEMTIME st;
+ FILETIME ft;
+
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ft);
+ t = SYS2UNIX_TIME(ft.dwLowDateTime, ft.dwHighDateTime);
+
+ if (ptime != NULL) {
+ *ptime = t;
+ }
+
+ return t;
+}
+
+static struct tm *localtime(const time_t *ptime, struct tm *ptm)
+{
+ int64_t t = ((int64_t) *ptime) * RATE_DIFF + EPOCH_DIFF;
+ FILETIME ft, lft;
+ SYSTEMTIME st;
+ TIME_ZONE_INFORMATION tzinfo;
+
+ if (ptm == NULL) {
+ return NULL;
+ }
+
+ * (int64_t *) &ft = t;
+ FileTimeToLocalFileTime(&ft, &lft);
+ FileTimeToSystemTime(&lft, &st);
+ ptm->tm_year = st.wYear - 1900;
+ ptm->tm_mon = st.wMonth - 1;
+ ptm->tm_wday = st.wDayOfWeek;
+ ptm->tm_mday = st.wDay;
+ ptm->tm_hour = st.wHour;
+ ptm->tm_min = st.wMinute;
+ ptm->tm_sec = st.wSecond;
+ ptm->tm_yday = 0; /* hope nobody uses this */
+ ptm->tm_isdst =
+ GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT ? 1 : 0;
+
+ return ptm;
+}
+
+static struct tm *gmtime(const time_t *ptime, struct tm *ptm)
+{
+ /* FIXME(lsm): fix this. */
+ return localtime(ptime, ptm);
+}
+
+static size_t strftime(char *dst, size_t dst_size, const char *fmt,
+ const struct tm *tm)
+{
+ (void) snprintf(dst, dst_size, "implement strftime() for WinCE");
+ return 0;
+}
+#endif
+
+/* Windows happily opens files with some garbage at the end of file name.
+ For example, fopen("a.cgi ", "r") on Windows successfully opens
+ "a.cgi", despite one would expect an error back.
+ This function returns non-0 if path ends with some garbage. */
+static int path_cannot_disclose_cgi(const char *path)
+{
+ static const char *allowed_last_characters = "_-";
+ int last = path[strlen(path) - 1];
+ return isalnum(last) || strchr(allowed_last_characters, last) != NULL;
+}
+
+static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep)
+{
+ wchar_t wbuf[PATH_MAX];
+ WIN32_FILE_ATTRIBUTE_DATA info;
+
+ if (!is_file_in_memory(conn, path, filep)) {
+ to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
+ if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) {
+ filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
+ filep->modification_time = SYS2UNIX_TIME(
+ info.ftLastWriteTime.dwLowDateTime,
+ info.ftLastWriteTime.dwHighDateTime);
+ filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ /* If file name is fishy, reset the file structure and return
+ error.
+ Note it is important to reset, not just return the error, cause
+ functions like is_file_opened() check the struct. */
+ if (!filep->is_directory && !path_cannot_disclose_cgi(path)) {
+ memset(filep, 0, sizeof(*filep));
+ }
+ }
+ }
+
+ return filep->membuf != NULL || filep->modification_time != 0;
+}
+
+static int mg_remove(const char *path)
+{
+ wchar_t wbuf[PATH_MAX];
+ to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
+ return DeleteFileW(wbuf) ? 0 : -1;
+}
+
+static int mg_mkdir(const char *path, int mode)
+{
+ char buf[PATH_MAX];
+ wchar_t wbuf[PATH_MAX];
+
+ (void) mode;
+ mg_strlcpy(buf, path, sizeof(buf));
+ change_slashes_to_backslashes(buf);
+
+ (void) MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, ARRAY_SIZE(wbuf));
+
+ return CreateDirectoryW(wbuf, NULL) ? 0 : -1;
+}
+
+/* Implementation of POSIX opendir/closedir/readdir for Windows. */
+static DIR * opendir(const char *name)
+{
+ DIR *dir = NULL;
+ wchar_t wpath[PATH_MAX];
+ DWORD attrs;
+
+ if (name == NULL) {
+ SetLastError(ERROR_BAD_ARGUMENTS);
+ } else if ((dir = (DIR *) mg_malloc(sizeof(*dir))) == NULL) {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ } else {
+ to_unicode(name, wpath, ARRAY_SIZE(wpath));
+ attrs = GetFileAttributesW(wpath);
+ if (attrs != 0xFFFFFFFF &&
+ ((attrs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)) {
+ (void) wcscat(wpath, L"\\*");
+ dir->handle = FindFirstFileW(wpath, &dir->info);
+ dir->result.d_name[0] = '\0';
+ } else {
+ mg_free(dir);
+ dir = NULL;
+ }
+ }
+
+ return dir;
+}
+
+static int closedir(DIR *dir)
+{
+ int result = 0;
+
+ if (dir != NULL) {
+ if (dir->handle != INVALID_HANDLE_VALUE)
+ result = FindClose(dir->handle) ? 0 : -1;
+
+ mg_free(dir);
+ } else {
+ result = -1;
+ SetLastError(ERROR_BAD_ARGUMENTS);
+ }
+
+ return result;
+}
+
+static struct dirent *readdir(DIR *dir)
+{
+ struct dirent *result = 0;
+
+ if (dir) {
+ if (dir->handle != INVALID_HANDLE_VALUE) {
+ result = &dir->result;
+ (void) WideCharToMultiByte(CP_UTF8, 0,
+ dir->info.cFileName, -1, result->d_name,
+ sizeof(result->d_name), NULL, NULL);
+
+ if (!FindNextFileW(dir->handle, &dir->info)) {
+ (void) FindClose(dir->handle);
+ dir->handle = INVALID_HANDLE_VALUE;
+ }
+
+ } else {
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ }
+ } else {
+ SetLastError(ERROR_BAD_ARGUMENTS);
+ }
+
+ return result;
+}
+
+#ifndef HAVE_POLL
+static int poll(struct pollfd *pfd, int n, int milliseconds)
+{
+ struct timeval tv;
+ fd_set set;
+ int i, result;
+ SOCKET maxfd = 0;
+
+ tv.tv_sec = milliseconds / 1000;
+ tv.tv_usec = (milliseconds % 1000) * 1000;
+ FD_ZERO(&set);
+
+ for (i = 0; i < n; i++) {
+ FD_SET((SOCKET) pfd[i].fd, &set);
+ pfd[i].revents = 0;
+
+ if (pfd[i].fd > maxfd) {
+ maxfd = pfd[i].fd;
+ }
+ }
+
+ if ((result = select((int)maxfd + 1, &set, NULL, NULL, &tv)) > 0) {
+ for (i = 0; i < n; i++) {
+ if (FD_ISSET(pfd[i].fd, &set)) {
+ pfd[i].revents = POLLIN;
+ }
+ }
+ }
+
+ return result;
+}
+#endif /* HAVE_POLL */
+
+static void set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */)
+{
+ (void) conn; /* Unused. */
+ (void) SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0);
+}
+
+int mg_start_thread(mg_thread_func_t f, void *p)
+{
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+ /* Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 */
+ return ((_beginthread((void (__cdecl *)(void *)) f, USE_STACK_SIZE, p) == ((uintptr_t)(-1L))) ? -1 : 0);
+#else
+ return ((_beginthread((void (__cdecl *)(void *)) f, 0, p) == ((uintptr_t)(-1L))) ? -1 : 0);
+#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
+}
+
+/* Start a thread storing the thread context. */
+
+static int mg_start_thread_with_id(unsigned (__stdcall *f)(void *), void *p,
+ pthread_t *threadidptr)
+{
+ uintptr_t uip;
+ HANDLE threadhandle;
+ int result = -1;
+
+ uip = _beginthreadex(NULL, 0, (unsigned (__stdcall *)(void *)) f, p, 0,
+ NULL);
+ threadhandle = (HANDLE) uip;
+ if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) {
+ *threadidptr = threadhandle;
+ result = 0;
+ }
+
+ return result;
+}
+
+/* Wait for a thread to finish. */
+
+static int mg_join_thread(pthread_t threadid)
+{
+ int result;
+ DWORD dwevent;
+
+ result = -1;
+ dwevent = WaitForSingleObject(threadid, INFINITE);
+ if (dwevent == WAIT_FAILED) {
+ int err;
+
+ err = GetLastError();
+ DEBUG_TRACE("WaitForSingleObject() failed, error %d", err);
+ } else {
+ if (dwevent == WAIT_OBJECT_0) {
+ CloseHandle(threadid);
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
+static HANDLE dlopen(const char *dll_name, int flags)
+{
+ wchar_t wbuf[PATH_MAX];
+ (void) flags;
+ to_unicode(dll_name, wbuf, ARRAY_SIZE(wbuf));
+ return LoadLibraryW(wbuf);
+}
+
+static int dlclose(void *handle)
+{
+ int result;
+
+ if (FreeLibrary((HMODULE) handle) != 0) {
+ result = 0;
+ } else {
+ result = -1;
+ }
+
+ return result;
+}
+
+#if !defined(NO_CGI)
+#define SIGKILL 0
+static int kill(pid_t pid, int sig_num)
+{
+ (void) TerminateProcess(pid, sig_num);
+ (void) CloseHandle(pid);
+ return 0;
+}
+
+static void trim_trailing_whitespaces(char *s)
+{
+ char *e = s + strlen(s) - 1;
+ while (e > s && isspace(* (unsigned char *) e)) {
+ *e-- = '\0';
+ }
+}
+
+static pid_t spawn_process(struct mg_connection *conn, const char *prog,
+ char *envblk, char *envp[], int fdin,
+ int fdout, const char *dir)
+{
+ HANDLE me;
+ char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX],
+ cmdline[PATH_MAX], buf[PATH_MAX];
+ struct file file = STRUCT_FILE_INITIALIZER;
+ STARTUPINFOA si;
+ PROCESS_INFORMATION pi = { 0 };
+
+ (void) envp;
+
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+
+ /* TODO(lsm): redirect CGI errors to the error log file */
+ si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_HIDE;
+
+ me = GetCurrentProcess();
+ DuplicateHandle(me, (HANDLE) _get_osfhandle(fdin), me,
+ &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS);
+ DuplicateHandle(me, (HANDLE) _get_osfhandle(fdout), me,
+ &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
+
+ /* If CGI file is a script, try to read the interpreter line */
+ interp = conn->ctx->config[CGI_INTERPRETER];
+ if (interp == NULL) {
+ buf[0] = buf[1] = '\0';
+
+ /* Read the first line of the script into the buffer */
+ snprintf(cmdline, sizeof(cmdline), "%s%c%s", dir, '/', prog);
+ if (mg_fopen(conn, cmdline, "r", &file)) {
+ p = (char *) file.membuf;
+ mg_fgets(buf, sizeof(buf), &file, &p);
+ mg_fclose(&file);
+ buf[sizeof(buf) - 1] = '\0';
+ }
+
+ if (buf[0] == '#' && buf[1] == '!') {
+ trim_trailing_whitespaces(buf + 2);
+ } else {
+ buf[2] = '\0';
+ }
+ interp = buf + 2;
+ }
+
+ if (interp[0] != '\0') {
+ GetFullPathNameA(interp, sizeof(full_interp), full_interp, NULL);
+ interp = full_interp;
+ }
+ GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL);
+
+ mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%s\"%s\\%s\"",
+ interp, interp[0] == '\0' ? "" : " ", full_dir, prog);
+
+ DEBUG_TRACE("Running [%s]", cmdline);
+ if (CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
+ CREATE_NEW_PROCESS_GROUP, envblk, NULL, &si, &pi) == 0) {
+ mg_cry(conn, "%s: CreateProcess(%s): %ld",
+ __func__, cmdline, ERRNO);
+ pi.hProcess = (pid_t) -1;
+ }
+
+ (void) CloseHandle(si.hStdOutput);
+ (void) CloseHandle(si.hStdInput);
+ if (pi.hThread != NULL)
+ (void) CloseHandle(pi.hThread);
+
+ return (pid_t) pi.hProcess;
+}
+#endif /* !NO_CGI */
+
+static int set_non_blocking_mode(SOCKET sock)
+{
+ unsigned long on = 1;
+ return ioctlsocket(sock, FIONBIO, &on);
+}
+
+#else
+static int mg_stat(struct mg_connection *conn, const char *path,
+ struct file *filep)
+{
+ struct stat st;
+
+ if (!is_file_in_memory(conn, path, filep) && !stat(path, &st)) {
+ filep->size = st.st_size;
+ filep->modification_time = st.st_mtime;
+ filep->is_directory = S_ISDIR(st.st_mode);
+ } else {
+ filep->modification_time = (time_t) 0;
+ }
+
+ return filep->membuf != NULL || filep->modification_time != (time_t) 0;
+}
+
+static void set_close_on_exec(int fd, struct mg_connection *conn /* may be null */)
+{
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
+ if (conn) {
+ mg_cry(conn, "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", __func__, strerror(ERRNO));
+ }
+ }
+}
+
+int mg_start_thread(mg_thread_func_t func, void *param)
+{
+ pthread_t thread_id;
+ pthread_attr_t attr;
+ int result;
+
+ (void) pthread_attr_init(&attr);
+ (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+ /* Compile-time option to control stack size,
+ e.g. -DUSE_STACK_SIZE=16384 */
+ (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
+#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
+
+ result = pthread_create(&thread_id, &attr, func, param);
+ pthread_attr_destroy(&attr);
+
+ return result;
+}
+
+/* Start a thread storing the thread context. */
+
+static int mg_start_thread_with_id(mg_thread_func_t func, void *param, pthread_t *threadidptr)
+{
+ pthread_t thread_id;
+ pthread_attr_t attr;
+ int result;
+
+ (void) pthread_attr_init(&attr);
+
+#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
+ /* Compile-time option to control stack size,
+ e.g. -DUSE_STACK_SIZE=16384 */
+ (void) pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
+#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */
+
+ result = pthread_create(&thread_id, &attr, func, param);
+ pthread_attr_destroy(&attr);
+ if ((result == 0) && (threadidptr != NULL)) {
+ *threadidptr = thread_id;
+ }
+ return result;
+}
+
+/* Wait for a thread to finish. */
+
+static int mg_join_thread(pthread_t threadid)
+{
+ int result;
+
+ result = pthread_join(threadid, NULL);
+ return result;
+}
+
+#ifndef NO_CGI
+static pid_t spawn_process(struct mg_connection *conn, const char *prog,
+ char *envblk, char *envp[], int fdin,
+ int fdout, const char *dir)
+{
+ pid_t pid;
+ const char *interp;
+
+ (void) envblk;
+
+ if ((pid = fork()) == -1) {
+ /* Parent */
+ send_http_error(conn, 500, NULL,
+ "Error: Creating CGI process\nfork(): %s", strerror(ERRNO));
+ } else if (pid == 0) {
+ /* Child */
+ if (chdir(dir) != 0) {
+ mg_cry(conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO));
+ } else if (dup2(fdin, 0) == -1) {
+ mg_cry(conn, "%s: dup2(%d, 0): %s", __func__, fdin, strerror(ERRNO));
+ } else if (dup2(fdout, 1) == -1) {
+ mg_cry(conn, "%s: dup2(%d, 1): %s", __func__, fdout, strerror(ERRNO));
+ } else {
+ /* Not redirecting stderr to stdout, to avoid output being littered
+ with the error messages. */
+ (void) close(fdin);
+ (void) close(fdout);
+
+ /* After exec, all signal handlers are restored to their default
+ values, with one exception of SIGCHLD. According to
+ POSIX.1-2001 and Linux's implementation, SIGCHLD's handler will
+ leave unchanged after exec if it was set to be ignored. Restore
+ it to default action. */
+ signal(SIGCHLD, SIG_DFL);
+
+ interp = conn->ctx->config[CGI_INTERPRETER];
+ if (interp == NULL) {
+ (void) execle(prog, prog, NULL, envp);
+ mg_cry(conn, "%s: execle(%s): %s", __func__, prog, strerror(ERRNO));
+ } else {
+ (void) execle(interp, interp, prog, NULL, envp);
+ mg_cry(conn, "%s: execle(%s %s): %s", __func__, interp, prog,
+ strerror(ERRNO));
+ }
+ }
+ exit(EXIT_FAILURE);
+ }
+
+ return pid;
+}
+#endif /* !NO_CGI */
+
+static int set_non_blocking_mode(SOCKET sock)
+{
+ int flags;
+
+ flags = fcntl(sock, F_GETFL, 0);
+ (void) fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+
+ return 0;
+}
+#endif /* _WIN32 */
+
+/* Write data to the IO channel - opened file descriptor, socket or SSL
+ descriptor. Return number of bytes written. */
+static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
+{
+ int64_t sent;
+ int n, k;
+
+ (void) ssl; /* Get rid of warning */
+ sent = 0;
+ while (sent < len) {
+
+ /* How many bytes we send in this iteration */
+ k = len - sent > INT_MAX ? INT_MAX : (int) (len - sent);
+
+#ifndef NO_SSL
+ if (ssl != NULL) {
+ n = SSL_write(ssl, buf + sent, k);
+ } else
+#endif
+ if (fp != NULL) {
+ n = (int) fwrite(buf + sent, 1, (size_t) k, fp);
+ if (ferror(fp))
+ n = -1;
+ } else {
+ n = send(sock, buf + sent, (size_t) k, MSG_NOSIGNAL);
+ }
+
+ if (n <= 0)
+ break;
+
+ sent += n;
+ }
+
+ return sent;
+}
+
+/* Read from IO channel - opened file descriptor, socket, or SSL descriptor.
+ Return negative value on error, or number of bytes read on success. */
+static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len)
+{
+ int nread;
+
+ if (fp != NULL) {
+ /* Use read() instead of fread(), because if we're reading from the
+ CGI pipe, fread() may block until IO buffer is filled up. We cannot
+ afford to block and must pass all read bytes immediately to the
+ client. */
+ nread = read(fileno(fp), buf, (size_t) len);
+#ifndef NO_SSL
+ } else if (conn->ssl != NULL) {
+ nread = SSL_read(conn->ssl, buf, len);
+#endif
+ } else {
+ nread = recv(conn->client.sock, buf, (size_t) len, 0);
+ }
+
+ return conn->ctx->stop_flag ? -1 : nread;
+}
+
+static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
+{
+ int n, nread = 0;
+
+ while (len > 0 && conn->ctx->stop_flag == 0) {
+ n = pull(fp, conn, buf + nread, len);
+ if (n < 0) {
+ nread = n; /* Propagate the error */
+ break;
+ } else if (n == 0) {
+ break; /* No more data to read */
+ } else {
+ conn->consumed_content += n;
+ nread += n;
+ len -= n;
+ }
+ }
+
+ return nread;
+}
+
+int mg_read(struct mg_connection *conn, void *buf, size_t len)
+{
+ int64_t n, buffered_len, nread;
+ int64_t len64 = (int64_t)(len > INT_MAX ? INT_MAX : len); /* since the return value is int, we may not read more bytes */
+ const char *body;
+
+ /* If Content-Length is not set for a PUT or POST request, read until socket is closed */
+ if (conn->consumed_content == 0 && conn->content_len == -1) {
+ conn->content_len = INT64_MAX;
+ conn->must_close = 1;
+ }
+
+ nread = 0;
+ if (conn->consumed_content < conn->content_len) {
+ /* Adjust number of bytes to read. */
+ int64_t left_to_read = conn->content_len - conn->consumed_content;
+ if (left_to_read < len64) {
+ /* Do not reade more than the total content length of the request. */
+ len64 = left_to_read;
+ }
+
+ /* Return buffered data */
+ buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len - conn->consumed_content;
+ if (buffered_len > 0) {
+ if (len64 < buffered_len) {
+ buffered_len = len64;
+ }
+ body = conn->buf + conn->request_len + conn->consumed_content;
+ memcpy(buf, body, (size_t) buffered_len);
+ len64 -= buffered_len;
+ conn->consumed_content += buffered_len;
+ nread += buffered_len;
+ buf = (char *) buf + buffered_len;
+ }
+
+ /* We have returned all buffered data. Read new data from the remote
+ socket. */
+ if ((n = pull_all(NULL, conn, (char *) buf, (int)len64)) >= 0) {
+ nread += n;
+ } else {
+ nread = (nread > 0 ? nread : n);
+ }
+ }
+ return (int)nread;
+}
+
+int mg_write(struct mg_connection *conn, const void *buf, size_t len)
+{
+ time_t now;
+ int64_t n, total, allowed;
+
+ if (conn->throttle > 0) {
+ if ((now = time(NULL)) != conn->last_throttle_time) {
+ conn->last_throttle_time = now;
+ conn->last_throttle_bytes = 0;
+ }
+ allowed = conn->throttle - conn->last_throttle_bytes;
+ if (allowed > (int64_t) len) {
+ allowed = len;
+ }
+ if ((total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
+ (int64_t) allowed)) == allowed) {
+ buf = (char *) buf + total;
+ conn->last_throttle_bytes += total;
+ while (total < (int64_t) len && conn->ctx->stop_flag == 0) {
+ allowed = conn->throttle > (int64_t) len - total ?
+ (int64_t) len - total : conn->throttle;
+ if ((n = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
+ (int64_t) allowed)) != allowed) {
+ break;
+ }
+ sleep(1);
+ conn->last_throttle_bytes = allowed;
+ conn->last_throttle_time = time(NULL);
+ buf = (char *) buf + n;
+ total += n;
+ }
+ }
+ } else {
+ total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
+ (int64_t) len);
+ }
+ return (int) total;
+}
+
+/* Alternative alloc_vprintf() for non-compliant C runtimes */
+static int alloc_vprintf2(char **buf, const char *fmt, va_list ap)
+{
+ va_list ap_copy;
+ int size = MG_BUF_LEN;
+ int len = -1;
+
+ *buf = NULL;
+ while (len == -1) {
+ if (*buf) mg_free(*buf);
+ *buf = (char *)mg_malloc(size *= 4);
+ if (!*buf) break;
+ va_copy(ap_copy, ap);
+ len = vsnprintf(*buf, size, fmt, ap_copy);
+ va_end(ap_copy);
+ }
+
+ return len;
+}
+
+/* Print message to buffer. If buffer is large enough to hold the message,
+ return buffer. If buffer is to small, allocate large enough buffer on heap,
+ and return allocated buffer. */
+static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap)
+{
+ va_list ap_copy;
+ int len;
+
+ /* Windows is not standard-compliant, and vsnprintf() returns -1 if
+ buffer is too small. Also, older versions of msvcrt.dll do not have
+ _vscprintf(). However, if size is 0, vsnprintf() behaves correctly.
+ Therefore, we make two passes: on first pass, get required message
+ length.
+ On second pass, actually print the message. */
+ va_copy(ap_copy, ap);
+ len = vsnprintf(NULL, 0, fmt, ap_copy);
+ va_end(ap_copy);
+
+ if (len < 0) {
+ /* C runtime is not standard compliant, vsnprintf() returned -1.
+ Switch to alternative code path that uses incremental allocations.
+ */
+ va_copy(ap_copy, ap);
+ len = alloc_vprintf2(buf, fmt, ap);
+ va_end(ap_copy);
+ } else if (len > (int) size &&
+ (size = len + 1) > 0 &&
+ (*buf = (char *) mg_malloc(size)) == NULL) {
+ len = -1; /* Allocation failed, mark failure */
+ } else {
+ va_copy(ap_copy, ap);
+ IGNORE_UNUSED_RESULT(vsnprintf(*buf, size, fmt, ap_copy));
+ va_end(ap_copy);
+ }
+
+ return len;
+}
+
+int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap)
+{
+ char mem[MG_BUF_LEN], *buf = mem;
+ int len;
+
+ if ((len = alloc_vprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
+ len = mg_write(conn, buf, (size_t) len);
+ }
+ if (buf != mem && buf != NULL) {
+ mg_free(buf);
+ }
+
+ return len;
+}
+
+int mg_printf(struct mg_connection *conn, const char *fmt, ...)
+{
+ va_list ap;
+ int result;
+
+ va_start(ap, fmt);
+ result = mg_vprintf(conn, fmt, ap);
+ va_end(ap);
+
+ return result;
+}
+
+int mg_url_decode(const char *src, int src_len, char *dst,
+ int dst_len, int is_form_url_encoded)
+{
+ int i, j, a, b;
+#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
+
+ for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) {
+ if (i < src_len - 2 && src[i] == '%' &&
+ isxdigit(* (const unsigned char *) (src + i + 1)) &&
+ isxdigit(* (const unsigned char *) (src + i + 2))) {
+ a = tolower(* (const unsigned char *) (src + i + 1));
+ b = tolower(* (const unsigned char *) (src + i + 2));
+ dst[j] = (char) ((HEXTOI(a) << 4) | HEXTOI(b));
+ i += 2;
+ } else if (is_form_url_encoded && src[i] == '+') {
+ dst[j] = ' ';
+ } else {
+ dst[j] = src[i];
+ }
+ }
+
+ dst[j] = '\0'; /* Null-terminate the destination */
+
+ return i >= src_len ? j : -1;
+}
+
+int mg_get_var(const char *data, size_t data_len, const char *name,
+ char *dst, size_t dst_len)
+{
+ return mg_get_var2(data,data_len,name,dst,dst_len,0);
+}
+
+int mg_get_var2(const char *data, size_t data_len, const char *name,
+ char *dst, size_t dst_len, size_t occurrence)
+{
+ const char *p, *e, *s;
+ size_t name_len;
+ int len;
+
+ if (dst == NULL || dst_len == 0) {
+ len = -2;
+ } else if (data == NULL || name == NULL || data_len == 0) {
+ len = -1;
+ dst[0] = '\0';
+ } else {
+ name_len = strlen(name);
+ e = data + data_len;
+ len = -1;
+ dst[0] = '\0';
+
+ /* data is "var1=val1&var2=val2...". Find variable first */
+ for (p = data; p + name_len < e; p++) {
+ if ((p == data || p[-1] == '&') && p[name_len] == '=' &&
+ !mg_strncasecmp(name, p, name_len) && 0 == occurrence--) {
+
+ /* Point p to variable value */
+ p += name_len + 1;
+
+ /* Point s to the end of the value */
+ s = (const char *) memchr(p, '&', (size_t)(e - p));
+ if (s == NULL) {
+ s = e;
+ }
+ assert(s >= p);
+
+ /* Decode variable into destination buffer */
+ len = mg_url_decode(p, (int)(s - p), dst, (int)dst_len, 1);
+
+ /* Redirect error code from -1 to -2 (destination buffer too
+ small). */
+ if (len == -1) {
+ len = -2;
+ }
+ break;
+ }
+ }
+ }
+
+ return len;
+}
+
+int mg_get_cookie(const char *cookie_header, const char *var_name,
+ char *dst, size_t dst_size)
+{
+ const char *s, *p, *end;
+ int name_len, len = -1;
+
+ if (dst == NULL || dst_size == 0) {
+ len = -2;
+ } else if (var_name == NULL || (s = cookie_header) == NULL) {
+ len = -1;
+ dst[0] = '\0';
+ } else {
+ name_len = (int) strlen(var_name);
+ end = s + strlen(s);
+ dst[0] = '\0';
+
+ for (; (s = mg_strcasestr(s, var_name)) != NULL; s += name_len) {
+ if (s[name_len] == '=')
<TRUNCATED>