Example #1
0
static char *nchan_publisher_directive_parse(ngx_conf_t *cf, ngx_command_t *cmd, void *conf, ngx_int_t fail) {
  nchan_loc_conf_t     *lcf = conf;
  ngx_str_t            *val;
  ngx_int_t             i;
  
  nchan_conf_publisher_types_t *pubt = &lcf->pub;
  
  if(cf->args->nelts == 1){ //no arguments
    pubt->http=1;
    pubt->websocket=1;
  }
  else {
    for(i=1; i < cf->args->nelts; i++) {
      val = &((ngx_str_t *) cf->args->elts)[i];
      if(nchan_strmatch(val, 1, "http")) {
        pubt->http=1;
      }
      else if(nchan_strmatch(val, WEBSOCKET_STRINGS_N, WEBSOCKET_STRINGS)) {
        pubt->websocket=1;
      }
      else{
         if(fail) {
          ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "invalid %V value: %V", &cmd->name, val);
         }
        return NGX_CONF_ERROR;
      }
    }
  }
  
  return nchan_setup_handler(cf, conf, &nchan_pubsub_handler);
}
Example #2
0
static char *nchan_subscriber_directive_parse(ngx_conf_t *cf, ngx_command_t *cmd, void *conf, ngx_int_t fail) {
  nchan_loc_conf_t     *lcf = conf;
  ngx_str_t            *val;
  ngx_int_t             i;
  
  nchan_conf_subscriber_types_t *subt = &lcf->sub;
  
  if(cf->args->nelts == 1){ //no arguments
    subt->poll=0;
    subt->longpoll=1;
    subt->websocket=1;
    subt->eventsource=1;
  }
  else {
    for(i=1; i < cf->args->nelts; i++) {
      val = &((ngx_str_t *) cf->args->elts)[i];
      if(nchan_strmatch(val, LONGPOLL_STRINGS_N, LONGPOLL_STRINGS)) {
        subt->longpoll=1;
      }
      else if(nchan_strmatch(val, INTERVALPOLL_STRINGS_N, INTERVALPOLL_STRINGS)) {
        subt->poll=1;
      }
      else if(nchan_strmatch(val, WEBSOCKET_STRINGS_N, WEBSOCKET_STRINGS)) {
        subt->websocket=1;
      }
      else if(nchan_strmatch(val, EVENTSOURCE_STRINGS_N, EVENTSOURCE_STRINGS)) {
        subt->eventsource=1;
      }
      else if(nchan_strmatch(val, DISABLED_STRINGS_N, DISABLED_STRINGS)) {
        subt->poll=0;
        subt->longpoll=0;
        subt->websocket=0;
        subt->eventsource=0;
      }
      else {
        if(fail) {
          ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "invalid %V value: %V", &cmd->name, val);
        }
        return NGX_CONF_ERROR;
      }
    }
  }
  return nchan_setup_handler(cf, conf, &nchan_pubsub_handler);
}
Example #3
0
static char *nchan_pubsub_directive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
  ngx_str_t            *val;
  ngx_int_t             i;
  nchan_publisher_directive_parse(cf, cmd, conf, 0);
  nchan_subscriber_directive_parse(cf, cmd, conf, 0);
  for(i=1; i < cf->args->nelts; i++) {
    val = &((ngx_str_t *) cf->args->elts)[i];
    if(! nchan_strmatch(val, WEBSOCKET_STRINGS_N + EVENTSOURCE_STRINGS_N + LONGPOLL_STRINGS_N + INTERVALPOLL_STRINGS_N + DISABLED_STRINGS_N, WEBSOCKET_STRINGS, EVENTSOURCE_STRINGS, LONGPOLL_STRINGS, INTERVALPOLL_STRINGS, DISABLED_STRINGS)) {
      ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "invalid %V value: %V", &cmd->name, val);
      return NGX_CONF_ERROR;
    }
  }
  return nchan_setup_handler(cf, conf, &nchan_pubsub_handler);
}
Example #4
0
File: common.c Project: slact/nchan
static ngx_int_t subscriber_authorize_callback(ngx_int_t rc, ngx_http_request_t *sr, void *data) {
  nchan_subscribe_auth_request_data_t *d = data;
  subscriber_t                        *sub = d->sub;
  
  if(sub->status == DEAD) {
    nchan_requestmachine_request_cleanup_manual(d->subrequest);
    sub->fn->release(d->sub, 0);
  }
  else if (rc == NGX_HTTP_CLIENT_CLOSED_REQUEST) {
    //this shouldn't happen, but if it does, no big deal
    nchan_requestmachine_request_cleanup_manual(d->subrequest);
    sub->fn->release(d->sub, 1);
    sub->fn->respond_status(sub, NGX_HTTP_INTERNAL_SERVER_ERROR, NULL, NULL); //couldn't reach upstream
  }
  else if(rc == NGX_OK) {
    ngx_int_t        code = sr->headers_out.status;
    sub->fn->release(sub, 1);
    if(code >= 200 && code <299) {
      nchan_requestmachine_request_cleanup_manual(d->subrequest);
      nchan_subscriber_subscribe(sub, d->ch_id);
    }
    else {
      //forbidden, but with some data to forward to the subscriber
      ngx_http_request_t       *r = d->sub->request;
      ngx_str_t                *content_type;
      ngx_int_t                 content_length;
      ngx_chain_t              *request_chain = NULL;
      content_type = (sr->upstream->headers_in.content_type ? &sr->upstream->headers_in.content_type->value : NULL);
      content_length = nchan_subrequest_content_length(sr);
      if(content_length > 0) {
#if nginx_version >= 1013010
        request_chain = sr->out;
#else
        request_chain = sr->upstream->out_bufs;
#endif
      }
      //copy headers
      ngx_uint_t                       i;
      ngx_list_part_t                 *part = &sr->headers_out.headers.part;
      ngx_table_elt_t                 *header= part->elts;
      for (i = 0; /* void */ ; i++) {
        if (i >= part->nelts) {
          if (part->next == NULL) {
            break;
          }
          part = part->next;
          header = part->elts;
          i = 0;
        }
        if (!nchan_strmatch(&header[i].key, 4, "Content-Type", "Server", "Content-Length", "Connection")) {
          //copy header to main request's response
          nchan_add_response_header(r, &header[i].key, &header[i].value);
        }
      }
      
      if(content_type) {
        r->headers_out.content_type = *content_type;
      }
      r->headers_out.content_length_n = content_length;
      nchan_requestmachine_request_cleanup_on_request_finalize(d->subrequest, r);
      sub->fn->respond_status(sub, code, NULL, request_chain); //auto-closes subscriber
    }
  }
  else if(rc >= 500 && rc < 600) {
    nchan_requestmachine_request_cleanup_manual(d->subrequest);
    sub->fn->release(d->sub, 1);
    sub->fn->respond_status(sub, rc, NULL, NULL); //auto-closes subscriber
  }
  else {
    nchan_requestmachine_request_cleanup_manual(d->subrequest);
    sub->fn->release(d->sub, 1);
    d->sub->fn->respond_status(d->sub, NGX_HTTP_INTERNAL_SERVER_ERROR, NULL, NULL); //auto-closes subscriber
  }
  
  return NGX_OK;
}