Exemple #1
0
void ortc_presence(ortc_context* context, 
		   char* channel, 
		   void (*callback)(ortc_context*, char*, char*, ortc_presenceData*)){
  pthread_t pThread;
  ortc_presenceParams *p;
  int ret;

  if(context->state != CONNECTED){
    _ortc_exception(context, "Not connected");
  } else if(!channel || strlen(channel)==0){
    _ortc_exception(context, "Channel is null or empty");
  } else if(!_ortc_isValidInput(context, channel)) {
    _ortc_exception(context, "Channel has invalid characters");
  } else if(strlen(channel) > ORTC_CHANNEL_MAX_SIZE){
    _ortc_exception(context, "Channel size exceeds the limit of characters");
  } else if(!callback) {
    _ortc_exception(context, "Callback is empty");
  } else {
    p = (ortc_presenceParams *)malloc(sizeof(ortc_presenceParams));  
    if(p == NULL){
      callback(context, channel, "malloc ortc_presenceParams failed!", NULL);
      return;
    }
    p->isExtended = 0;
    p->context = context;
    p->channel = channel;
    p->callbackGet = callback;    
    ret = pthread_create(&pThread, NULL, _ortc_presence, p);
    if(ret!=0){
      callback(context, channel, "Error creating presence thread!", NULL);
      free(p);
    }
  }
}
Exemple #2
0
void ortc_save_authentication_ex(ortc_context *context, char* url, 
                                 int isCluster, char* authToken,
                                 int isPrivate, char* appKey,
                                 int ttl, char *privateKey,
                                 ortc_channelPermissions *permissions,
                                 int sizeOfChannelPermissions,
                                 void (*callback)(ortc_context*, char*, char*)){
  pthread_t pThread;
  ortc_authenticationParams *p;
  int ret;

  if(!permissions){
    _ortc_exception(context, "Channel permissions are empty");
  } else if(!callback) {
    _ortc_exception(context, "Callback is empty");
  } else if(!privateKey || strlen(privateKey)==0){
    _ortc_exception(context, "Private key is null or empty");
  } else if(!_ortc_isValidInput(context, privateKey)) {
    _ortc_exception(context, "Private key has invalid characters");
  } else if(!authToken || strlen(authToken)==0){
    _ortc_exception(context, "Authentication token is null or empty");
  } else if(!_ortc_isValidInput(context, authToken)) {
    _ortc_exception(context, "Authentication token has invalid characters");
  } else if(!appKey || strlen(appKey)==0) {
    _ortc_exception(context, "Application Key is null or empty");
  } else if(!_ortc_isValidInput(context, appKey)) {
    _ortc_exception(context, "Application Key has invalid characters");
  } else if(!url || strlen(url)==0){
    _ortc_exception(context, "Url is null or empty");
  } else if(url && !_ortc_isValidUrl(context, url)) { 
    _ortc_exception(context, "Invalid URL");
  } else {
    isCluster = (isCluster>0) ? 1 : 0;
    isPrivate = (isPrivate>0) ? 1 : 0;
    p = (ortc_authenticationParams *)malloc(sizeof(ortc_authenticationParams));  
    if(p == NULL){
      callback(context, "malloc ortc_authenticationParams failed", NULL);
      return;
    }
    p->isExtended = 1;
    p->context = context;
    p->url = url;
    p->isCluster = isCluster;
    p->appKey = appKey;
    p->authToken = authToken;
    p->isPrivate = isPrivate;
    p->ttl = ttl;
    p->privateKey = privateKey;
    p->permissions = permissions;
    p->sizeOfChannelPermissions = sizeOfChannelPermissions;
    p->callback = callback;  
    ret = pthread_create(&pThread, NULL, _ortc_saveAuthentication, p);
    if(ret!=0){
      callback(context, "Error creating authentication thread!", NULL);
      free(p);
    }
  }
}
Exemple #3
0
void ortc_enable_presence_ex(ortc_context* context, 
                             char* url, 
                             int isCluster, 
                             char* appKey, 
                             char* privateKey, 
                             char* channel, 
                             int metadata, 
                             void (*callback)(ortc_context*, char*, char*, char*)){
  pthread_t pThread;
  ortc_presenceParams *p;
  int ret;

  if(!url || strlen(url)==0){
    _ortc_exception(context, "Url is null or empty");
  } else if (url && !_ortc_isValidUrl(context, url)) { 
    _ortc_exception(context, "Invalid URL");
  } else if (!appKey || strlen(appKey)==0) {
    _ortc_exception(context, "Application Key is null or empty");
  } else if (!_ortc_isValidInput(context, appKey)) {
    _ortc_exception(context, "Application Key has invalid characters");
  } else if(!channel || strlen(channel)==0){
    _ortc_exception(context, "Channel is null or empty");
  } else if(!_ortc_isValidInput(context, channel)) {
    _ortc_exception(context, "Channel has invalid characters");
  } else if(strlen(channel) > ORTC_CHANNEL_MAX_SIZE){
    _ortc_exception(context, "Channel size exceeds the limit of characters");
  } else if(!callback) {
    _ortc_exception(context, "Callback is empty");
  } else if(!privateKey || strlen(privateKey)==0){
    _ortc_exception(context, "Private key is null or empty");
  } else if(!_ortc_isValidInput(context, privateKey)) {
    _ortc_exception(context, "Private key has invalid characters");
  } else {
    isCluster = (isCluster>0) ? 1 : 0;
    metadata = (metadata>0) ? 1 : 0;

    p = (ortc_presenceParams *)malloc(sizeof(ortc_presenceParams));  
    if(p == NULL){
      callback(context, channel, "malloc ortc_presenceParams failed!", NULL);
      return;
    }
    p->isExtended = 1;
    p->url = url;
    p->isCluster = isCluster;
    p->appKey = appKey;
    p->context = context;
    p->privateKey = privateKey;
    p->channel = channel;
    p->metadata = metadata;
    p->callbackCmd = callback;    
    ret = pthread_create(&pThread, NULL, _ortc_enablePresence, p);
    if(ret!=0){
      callback(context, channel, "Error creating presence thread!", NULL);
      free(p);
    }
  }
}
void _ortc_send(ortc_context* context, char* channel, char* message){
  int i;
  size_t len;
  char *hash = _ortc_get_channel_permission(context, channel);
  char messageId[9], sParts[15], sMessageCount[15];
    int messageCount = 0;
  char* messagePart, *m;
  size_t parts = strlen(message) / ORTC_MAX_MESSAGE_SIZE;

  _ortc_random_string(messageId, 9);
  if(strlen(message) % ORTC_MAX_MESSAGE_SIZE > 0)
    parts++;
  sprintf(sParts, "%d", (int)parts);

  for(i=0; i<parts; i++){
    size_t messageSize;
    char *messageR;
    messageSize = strlen(message) - i * ORTC_MAX_MESSAGE_SIZE;
    if(messageSize > ORTC_MAX_MESSAGE_SIZE)
      messageSize = ORTC_MAX_MESSAGE_SIZE;
    
    messageCount = i + 1;    
    
    sprintf(sMessageCount, "%d", messageCount);

    messagePart = (char*)malloc(messageSize+1);
    if(messagePart==NULL){
      _ortc_exception(context, "malloc() failed in ortc send!");
      return;
    }
    memcpy(messagePart, message + i * ORTC_MAX_MESSAGE_SIZE, messageSize);
    messagePart[messageSize] = '\0';

    messageR = _ortc_escape_sequences_before(messagePart);
  
    len = 15 + strlen(context->appKey) + strlen(context->authToken) + strlen(channel) + strlen(hash) + strlen(messageId) + strlen(sParts) + strlen(sMessageCount) + strlen(messageR); 
    m = (char*)malloc(len + 1);
    if(m == NULL){
      _ortc_exception(context, "malloc() failed in ortc send!");
      free(messagePart);
      free(messageR);
      return;
    }
    snprintf(m, len, "\"send;%s;%s;%s;%s;%s_%d-%d_%s\"", context->appKey, context->authToken, channel, hash, messageId, messageCount, (int)parts, messageR);
    free(messagePart);
    free(messageR);
    _ortc_send_message(context, m);
  }
}
Exemple #5
0
void ortc_send(ortc_context* context, char *channel, char *message){
  if(context->state != CONNECTED){
    _ortc_exception(context, "Not connected");
  } else if(!channel || strlen(channel)==0){
    _ortc_exception(context, "Channel is null or empty");
  } else if(!_ortc_isValidInput(context, channel)) {
    _ortc_exception(context, "Channel has invalid characters");
  } else if(!message || strlen(message)==0){
    _ortc_exception(context, "Message is null or empty");
  } else if(strlen(channel) > ORTC_CHANNEL_MAX_SIZE){
    _ortc_exception(context, "Channel size exceeds the limit of characters");
  } else {
    _ortc_send(context, channel, message);
  }
}
Exemple #6
0
void _ortc_save_permissions(ortc_context *context, char *permissions){
  int rc, offset = 0;
  regex_t rePerm; 
  size_t     nmatch = 3;
  regmatch_t pmatch[3];
  char *channel, *hash;

  _ortc_dlist_clear(context->permissions);
  if(strcmp(permissions, "null")!=0){

    if (0 != (rc = regcomp(&rePerm, "\\\\\"\\(.[^\\\\\"]*\\)\\\\\":\\\\\"\\(.[^\\\\\"]*\\)\\\\\"", 0))) {
      _ortc_exception(context, "regcomp() failed, returning nonzero in ortc save permissions");
      return;
    }

    while(1){
      if(regexec(&rePerm, permissions + offset, nmatch, pmatch, 0))
	break;
      channel = _ortc_get_from_regmatch(permissions, pmatch[1]);
      hash = _ortc_get_from_regmatch(permissions + offset, pmatch[2]);
      _ortc_dlist_insert(context->permissions, channel, hash, NULL, 0, NULL);
      offset += pmatch[2].rm_eo;
      free(channel);
      free(hash);
    }
    regfree(&rePerm);
  }
}
Exemple #7
0
void ortc_disconnect(ortc_context* context){
  if(context->state != DISCONNECTED){    
    _ortc_disconnect(context);
  } else {
    _ortc_exception(context,  "Not connected!"); 
  }
}
int _ortc_prepare_websocket(ortc_context* context){
  struct lws_context_creation_info info;

  if(context->lws_context)
    libwebsocket_context_destroy(context->lws_context);
  context->lws_context = NULL;
  if(context->host)
    free(context->host);
  context->host = NULL;
  if(context->server)
    free(context->server);
  context->server = NULL;

  memset(&info, 0, sizeof info);
  info.port = CONTEXT_PORT_NO_LISTEN;
  info.gid = -1;
  info.uid = -1;
  info.protocols = ortc_protocols;
  info.ssl_cipher_list = "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL";

  info.ka_time = 0;
  info.ka_interval = 0;
  info.ka_probes = 0;
  
  context->lws_context = libwebsocket_create_context(&info);
  if (context->lws_context == NULL) {
    _ortc_exception(context,  "Creating libwebsocket context failed!");
    return -1;
  }
  return 0;
}
Exemple #9
0
void ortc_unsubscribe(ortc_context* context, char *channel){
  if(context->state != CONNECTED){
    _ortc_exception(context, "Not connected");
  } else if(!channel || strlen(channel)==0){
    _ortc_exception(context, "Channel is null or empty");
  } else if(!_ortc_isValidInput(context, channel)) {
    _ortc_exception(context, "Channel has invalid characters");
  } else if(!ortc_is_subscribed(context, channel)){
      char *ex_msg = _ortc_ch_ex_msg("Not subscribed to the channel", channel);
      _ortc_exception(context, ex_msg);
      free(ex_msg);
  } else if(strlen(channel) > ORTC_CHANNEL_MAX_SIZE){
    _ortc_exception(context, "Channel size exceeds the limit of characters");
  } else {
    _ortc_unsubscribe(context, channel);
  }
}
Exemple #10
0
void ortc_subscribe(ortc_context* context, 
		    char *channel, 
		    int subscribeOnReconnected, 
		    void (*onMessage)(ortc_context*, char*, char*)){
  if(context->state != CONNECTED){
    _ortc_exception(context, "Not connected");
  } else if(!channel || strlen(channel)==0){
    _ortc_exception(context, "Channel is null or empty");
  } else if(!_ortc_isValidInput(context, channel)) {
    _ortc_exception(context, "Channel has invalid characters");
  } else if(_ortc_is_subscribing(context, channel)){
      char *ex_msg = _ortc_ch_ex_msg("Already trying to subscribe this channel", channel);
      _ortc_exception(context, ex_msg);
      free(ex_msg);
  } else if(ortc_is_subscribed(context, channel)){
      char *ex_msg = _ortc_ch_ex_msg("Already subscribed to this channel", channel);
      _ortc_exception(context, ex_msg);
      free(ex_msg);
  } else if(strlen(channel) > ORTC_CHANNEL_MAX_SIZE){
    _ortc_exception(context, "Channel size exceeds the limit of characters");
  } else if(!onMessage){
    _ortc_exception(context, "The argument \"onMessage\" must point to a function");
  } else {
    _ortc_subscribe(context, channel, subscribeOnReconnected, 1, onMessage);
  }
}
void _ortc_fireOnReconnecting(ortc_context *context){
	pthread_t thr;
	if(context->onReconnecting != NULL){
		int tret = pthread_create(&thr, NULL, _ortc_job_onReconnecting, context);
		if(tret!=0){    
			_ortc_exception(context,  (char*)"Error creating event (onReconnecting) thread!");
		}
	}
}
Exemple #12
0
void _ortc_unsubscribe(ortc_context* context, char* channel){
  int len = 16 + strlen(context->appKey) + strlen(channel);
  char *unsubscribeCommand = (char*)malloc(len + 1);
  ortc_dnode *ch;

  if(unsubscribeCommand == NULL){
    _ortc_exception(context,  "malloc() failed in ortc unsubscribe");
    return;
  }
  ch = _ortc_dlist_search(context->channels, channel);
  if(ch != NULL)
    ch->num = -1; //is trying to unsbscribed
  snprintf(unsubscribeCommand, len, "\"unsubscribe;%s;%s\"", context->appKey, channel);
  _ortc_send_command(context, unsubscribeCommand);
}
Exemple #13
0
void _ortc_subscribe(ortc_context* context, char* channel, int subscribeOnReconnected, int toBeSaved, void (*onMessage)(ortc_context*, char*, char*)){
  char *hash = _ortc_get_channel_permission(context, channel);
  int len = 16 + strlen(context->appKey) + strlen(context->authToken) + strlen(channel) + strlen(hash);
  char *subscribeCommand = (char*)malloc(len + 1);

  if(subscribeCommand == NULL){
    _ortc_exception(context,  "malloc() failed in ortc subscribe");
    return;
  }
  subscribeOnReconnected = (subscribeOnReconnected>0)?1:0;
  if(toBeSaved)
    _ortc_dlist_insert(context->channels, channel, NULL, NULL, subscribeOnReconnected, (void(*)(ortc_context*, char*, char*))onMessage);
  snprintf(subscribeCommand, len, "\"subscribe;%s;%s;%s;%s\"", context->appKey, context->authToken, channel, hash);
  _ortc_send_command(context, subscribeCommand);
}
Exemple #14
0
void _ortc_parse_message(ortc_context *context, char *message){
  char *messageId, *messageCount, *messageTotal, *messagePart, *channelNameStr, *messageStr, *params, *permissionsStr, *exceptionStr, *validateString, *operationType;
  struct cap pmatch[3], pmatch2[5];
  int iMessageTotal, wsSock, opt;
  size_t len, hbLen;
  ortc_dnode *ch;
  char hbStr[24];
  
  if(message[0] == 'a') {
    if (slre_match(&context->reMessage, message, (int)strlen(message), pmatch)) {         //is message   
      channelNameStr = _ortc_get_from_slre(1, pmatch);
      messageStr = _ortc_get_from_slre(2, pmatch);
      if(slre_match(&context->reMultipart, messageStr, (int)strlen(messageStr), pmatch2)){
		messageId =    _ortc_get_from_slre(1, pmatch2);
		messageCount = _ortc_get_from_slre(2, pmatch2);
		messageTotal = _ortc_get_from_slre(3, pmatch2);
		messagePart =  _ortc_get_from_slre(4, pmatch2);
		iMessageTotal = atoi(messageTotal);
		if(iMessageTotal > 1){ //multipart message
			_ortc_dlist_insert(context->multiparts, messageId, channelNameStr, messagePart, atoi(messageCount), NULL);
		_ortc_check_if_got_all_parts(context, messageId, iMessageTotal);
		} else {
			_ortc_fire_onMessage(context, channelNameStr, messagePart);
		}
		free(messageId);
		free(messageCount);
		free(messageTotal);
		free(messagePart);
      } else {
        _ortc_fire_onMessage(context, channelNameStr, messageStr);
      }
      free(channelNameStr);
      free(messageStr);
    } else if (slre_match(&context->reOperation, message, (int)strlen(message), pmatch)) {
      params = _ortc_get_from_slre(2, pmatch);
      operationType = _ortc_get_from_slre(1, pmatch);
      if(strncmp(operationType, "ortc-validated", 14)==0){
		if(slre_match(&context->rePermissions, params, (int)strlen(params), pmatch2)){
			permissionsStr = _ortc_get_from_slre(1, pmatch2);
			_ortc_save_permissions(context, permissionsStr);
			free(permissionsStr);
		}
		_ortc_change_state(context, CONNECTED);
		
      } else if(strncmp(operationType, "ortc-subscribed", 15)==0){
	if(slre_match(&context->reChannel, params, (int)strlen(params), pmatch2)){
	  channelNameStr = _ortc_get_from_slre(1, pmatch2);
	  ch = _ortc_dlist_search(context->channels, channelNameStr);
	  if(ch != NULL)
	    ch->num += 2; //isSubscribed
	  if(context->onSubscribed != NULL)
	    context->onSubscribed(context, channelNameStr);	  
	  free(channelNameStr);
	}
      } else if(strncmp(operationType, "ortc-unsubscribed", 17)==0){
	if(slre_match(&context->reChannel, params, (int)strlen(params), pmatch2)){
	  channelNameStr = _ortc_get_from_slre(1, pmatch2);
	  _ortc_dlist_delete(context->channels, channelNameStr);
	  if(context->onUnsubscribed != NULL)
	    context->onUnsubscribed(context, channelNameStr);
	  free(channelNameStr);
	}
      } else if(strncmp(operationType, "ortc-error", 10)==0){
	if(slre_match(&context->reException, params, (int)strlen(params), pmatch2)){
		_ortc_cancel_connecting(context);
		exceptionStr = _ortc_get_from_slre(1, pmatch2);
		_ortc_exception(context, exceptionStr);
		free(exceptionStr);
	}
      }
      free(params);
      free(operationType);
    }

  } else if(message[0] == 'o' && strlen(message)==1){
    wsSock = libwebsocket_get_socket_fd(context->wsi);
    opt = ORTC_SNDBUF_SIZE;
    setsockopt(wsSock, SOL_SOCKET, SO_SNDBUF, (const char*)&opt, sizeof(opt));
	
	
	if(context->heartbeatActive){
		snprintf(hbStr, sizeof(hbStr), "%d;%d;", context->heartbeatTime, context->heartbeatFails);
		hbLen = strlen(hbStr);
	} else {
		hbLen = 0;
	}
    len = 17 + strlen(context->appKey) +  strlen(context->authToken) + strlen(context->announcementSubChannel) + strlen(context->sessionId) + strlen(context->metadata) + hbLen;
	
    validateString = malloc(len+1);
    if(validateString == NULL){
      _ortc_exception(context, "malloc() failed in ortc parese message");
      return;
    }
	if(context->heartbeatActive)
		snprintf(validateString, len, "\"validate;%s;%s;%s;%s;%s;%s\"", context->appKey, context->authToken, context->announcementSubChannel, context->sessionId, context->metadata, hbStr);
	else
		snprintf(validateString, len, "\"validate;%s;%s;%s;%s;%s;\"", context->appKey, context->authToken, context->announcementSubChannel, context->sessionId, context->metadata);
    _ortc_send_command(context, validateString);
	
  } else if(strncmp(message, "c[1000,\"Normal closure\"]", 20)==0){
	_ortc_exception(context, "Server is about to close the websocket!");
  }
}
Exemple #15
0
void ortc_connect(ortc_context* context, char* applicationKey, char* authenticationToken){
  int tret;
  if(context->state == CONNECTED){
    _ortc_exception(context, "Already connected");
  } else if (context->state != DISCONNECTED){
	_ortc_exception(context, "Already trying to connect");
  } else if (!context->url && !context->cluster){
    _ortc_exception(context, "URL and Cluster URL are null or empty");
  } else if (!applicationKey || strlen(applicationKey)==0) {
    _ortc_exception(context, "Application Key is null or empty");
  } else if (!authenticationToken || strlen(authenticationToken)==0) {
    _ortc_exception(context, "Authentication Token is null or empty");    
  } else if (context->url && !_ortc_isValidUrl(context, context->url)) { 
    _ortc_exception(context, "Invalid URL");
  } else if (context->cluster && !_ortc_isValidUrl(context, context->cluster)) {
    _ortc_exception(context, "Invalid Cluster URL");
  } else if (!_ortc_isValidInput(context, applicationKey)) {
    _ortc_exception(context, "Application Key has invalid characters");
  } else if (!_ortc_isValidInput(context, authenticationToken)) {
    _ortc_exception(context, "Authentication Token has invalid characters");
  } else if (!_ortc_isValidInput(context, context->announcementSubChannel)) {
    _ortc_exception(context, "Announcement Subchannel has invalid characters");
  } else if (strlen(context->metadata) > ORTC_CONNECTION_METADATA_MAX_SIZE){
    _ortc_exception(context, "Connection metadata size exceeds the limit");
  } else {
    context->appKey = applicationKey;
    context->authToken = authenticationToken;
	_ortc_init_connection(context);
  }
}