示例#1
0
文件: ad_plugin.c 项目: dmlloyd/Carla
void *ad_open(const char *fn, struct adinfo *nfo) {
	adecoder *d = (adecoder*) calloc(1, sizeof(adecoder));
	ad_clear_nfo(nfo);

	d->b = choose_backend(fn);
	if (!d->b) {
		dbg(0, "fatal: no decoder backend available");
		free(d);
		return NULL;
	}
	d->d = d->b->open(fn, nfo);
	if (!d->d) {
		free(d);
		return NULL;
	}
	return (void*)d;
}
示例#2
0
/*
 * choose_backend parses incoming HTTP request and routes it to the appropriate
 * backend. It assumes that clients don't do HTTP pipelining, handling only
 * one request request for each connection. To give a hint to backend about
 * this it inserts "Connection: close" header into each forwarded request.
 */
static int connect_backend(struct conn_data *conn, struct http_message *hm) {
  struct mg_connection *nc = conn->client.nc;
  struct http_backend *be = choose_backend(hm);

  write_log("%ld %.*s %.*s backend=%s\n", (long) time(NULL),
            (int) hm->method.len, hm->method.p, (int) hm->uri.len, hm->uri.p,
            be ? be->host_port : "not defined");

  if (be == NULL) return 0;
  if (be->redirect != 0) {
    mg_printf(nc, "HTTP/1.1 302 Found\r\nLocation: %s\r\n\r\n", be->host_port);
    return 1;
  }
  struct be_conn *bec = get_conn(be);
  if (bec != NULL) {
    bec->nc->handler = ev_handler;
#ifdef DEBUG
    write_log("conn=%p to %p (%s) reusing bec=%p\n", conn, be, be->host_port,
              bec);
#endif
  } else {
    bec = malloc(sizeof(*conn->be_conn));
    memset(bec, 0, sizeof(*bec));
    bec->nc = mg_connect(nc->mgr, be->host_port, ev_handler);
#ifdef DEBUG
    write_log("conn=%p new conn to %p (%s) bec=%p\n", conn, be, be->host_port,
              bec);
#endif
    if (bec->nc == NULL) {
      free(bec);
      write_log("Connection to [%s] failed\n", be->host_port);
      return 0;
    }
  }
  bec->be = be;
  conn->be_conn = bec;
  conn->backend.nc = bec->nc;
  conn->backend.nc->user_data = conn;
  mg_set_protocol_http_websocket(conn->backend.nc);
  return 1;
}
示例#3
0
static void ev_handler(struct ns_connection *nc, int ev, void *ev_data) {
  struct iobuf *io = &nc->recv_iobuf;
  struct ns_connection *peer = (struct ns_connection *) nc->proto_data;

  switch (ev) {
    case NS_CONNECT:
      if (* (int *) ev_data != 0) {
        /* TODO(lsm): mark backend as defunct, try it later on */
        fprintf(stderr, "connect(%s) failed\n",
                s_http_backends[(int) nc->user_data].host_port);
        ns_printf(nc->proto_data, "%s%s\r\n", s_error_500, s_content_len_0);
      }
      break;
    case NS_RECV:
      /*
       * For incoming client connection, nc->proto_data points to the respective
       * backend connection. For backend connection, nc->proto_data points
       * to the respective incoming client connection.
       */
      if (peer == NULL) {
        choose_backend(nc);
      } else {
        /* Forward data to peer */
        ns_send(peer, io->buf, io->len);
        iobuf_remove(io, io->len);
      }
      break;
    case NS_CLOSE:
      /* We're closing, detach our peer */
      if (peer != NULL) {
        peer->proto_data = NULL;
        peer->flags |= NSF_SEND_AND_CLOSE;
      }
      break;
  }
}