示例#1
0
static ngx_int_t websocket_publish(full_subscriber_t *fsub, ngx_str_t *msg_str) {
  nchan_msg_t              msg;
  ngx_buf_t                buf;
  static ngx_str_t         nopublishing = ngx_string("Publishing not allowed.");
  
  if(!fsub->sub.cf->pub.websocket) {
    return websocket_send_close_frame(fsub, CLOSE_POLICY_VIOLATION, &nopublishing);
  }
  
  ngx_http_request_t   *r = fsub->request;
  
  init_msg_buf(&buf);
  buf.start = msg_str->data;
  buf.pos = buf.start;
  buf.end = buf.start + msg_str->len;
  buf.last = buf.end;
  
  ngx_memzero(&msg, sizeof(msg));
  
  msg.buf=&buf;
  if(r->headers_in.content_type) {
    msg.content_type.data = r->headers_in.content_type->value.data;
    msg.content_type.len = r->headers_in.content_type->value.len;
  }
  
  fsub->sub.cf->storage_engine->publish(fsub->publish_channel_id, &msg, fsub->sub.cf, (callback_pt )websocket_publish_callback, fsub);
  
  return NGX_OK;
}
示例#2
0
static ngx_int_t websocket_publish(full_subscriber_t *fsub, ngx_buf_t *buf) {
  static ngx_str_t         nopublishing = ngx_string("Publishing not allowed.");
  static ngx_str_t         POST_REQUEST_STRING = {4, (u_char *)"POST "};
  
  if(!fsub->sub.cf->pub.websocket) {
    return websocket_send_close_frame(fsub, CLOSE_POLICY_VIOLATION, &nopublishing);
  }
  
#if (NGX_DEBUG_POOL)
  ERR("ws request pool size: %V", ngx_http_debug_pool_str(fsub->sub.request->pool));
#endif
  
  ngx_http_complex_value_t        *publisher_upstream_request_url_ccv;
  
  publisher_upstream_request_url_ccv = fsub->sub.cf->publisher_upstream_request_url;
  if(publisher_upstream_request_url_ccv == NULL) {
    websocket_publish_continue(fsub, buf);
  }
  else {
    nchan_pub_upstream_stuff_t    *psr_stuff;
    ngx_http_post_subrequest_t    *psr;
    nchan_pub_upstream_data_t     *psrd;
    ngx_http_request_t            *r = fsub->sub.request;
    ngx_http_request_t            *sr;
    ngx_http_request_body_t       *fakebody;
    ngx_chain_t                   *fakebody_chain;
    ngx_buf_t                     *fakebody_buf;
    size_t                         sz;
    
    if(!fsub->upstream_stuff) {
      
      if((psr_stuff = ngx_palloc(r->pool, sizeof(*psr_stuff))) == NULL) {
        ERR("can't allocate memory for publisher auth subrequest");
        websocket_respond_status(&fsub->sub, NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
        return NGX_ERROR;
      }
      
      fsub->upstream_stuff = psr_stuff;
      psr = &psr_stuff->psr;
      psr->data = &psr_stuff->psr_data;
      psr->handler = websocket_publisher_upstream_handler;
      psr_stuff->psr_data.fsub = fsub;
      
      psr_stuff->psr_data.tmp_pool = NULL;
      
      ngx_http_complex_value(r, publisher_upstream_request_url_ccv, &psr_stuff->psr_data.upstream_request_url); 
    }
    
    psrd = &fsub->upstream_stuff->psr_data;
    psr = &fsub->upstream_stuff->psr;
    
    if(psrd->tmp_pool) {
      //previous upstream request's pool
      ngx_destroy_pool(psrd->tmp_pool);
      psrd->tmp_pool = NULL;
    }
    
    psrd->buf = *buf;
    psrd->original_pool = r->pool;
    psrd->original_cleanup = r->cleanup;
    r->cleanup = NULL;
    
    psrd->tmp_pool = ngx_create_pool(NCHAN_WS_UPSTREAM_TMP_POOL_SIZE, r->connection->log);
    
    r->pool = psrd->tmp_pool;
    //ERR("request %p tmp pool %p", r, r->pool);
    
    fakebody = ngx_pcalloc(r->pool, sizeof(*fakebody));
    if(ngx_buf_size(buf) > 0) {
      fakebody_chain = ngx_palloc(r->pool, sizeof(*fakebody_chain));
      fakebody_buf = ngx_palloc(r->pool, sizeof(*fakebody_buf));
      fakebody->bufs = fakebody_chain;
      fakebody_chain->next = NULL;
      fakebody_chain->buf = fakebody_buf;
      init_msg_buf(fakebody_buf);
      
      //just copy the buffer contents. it's inefficient but I don't care at the moment.
      //this can and should be optimized later
      sz = ngx_buf_size(buf);
      fakebody_buf->start = ngx_palloc(r->pool, sz); //huuh?
      ngx_memcpy(fakebody_buf->start, buf->start, sz);
      fakebody_buf->end = fakebody_buf->start + sz;
      fakebody_buf->pos = fakebody_buf->start;
      fakebody_buf->last = fakebody_buf->end;
    }
    else {
      sz = 0;
    }
    
    ngx_http_subrequest(r, &psrd->upstream_request_url, NULL, &sr, psr, NGX_HTTP_SUBREQUEST_IN_MEMORY);
    nchan_adjust_subrequest(sr, NGX_HTTP_POST, &POST_REQUEST_STRING, fakebody, sz, NULL);
    
    /*
    //http request sudden close cleanup
    if((psrd->cln = ngx_http_cleanup_add(sr, 0)) == NULL) {
      ERR("Unable to add request cleanup for websocket upstream request");
      return NGX_ERROR;
    }
    psrd->cln->data = fsub;
    psrd->cln->handler = (ngx_http_cleanup_pt )sudden_upstream_request_abort_handler;
    */
  }
  
  return NGX_OK;
}