Example #1
0
// Renders the response
void renderResponse(struct ns_connection *nc, const SharedMemory* sharedData, struct http_message *hm)  {

	std::string responseJson = sharedMemoryRenderer.render(sharedData, getQueryString(hm));
	std::string response;

	bool gzipResponse = shouldGzipResponse(hm, responseJson.size());

	if (gzipResponse)	{
		response = Utils::gzipString(responseJson);
	}else{
		response = responseJson;
	}

	// build HTTP OK response with JSON response body
	ns_printf(nc, "HTTP/1.1 200 OK\r\n"
		"Content-Type: application/json\r\n"
		"Cache-Control: no-cache\r\n"
        "Access-Control-Allow-Origin: *\r\n");
	if (gzipResponse)	{
		ns_printf(nc, "Content-Encoding: gzip\r\n");
	}
	ns_printf(nc, "Content-Length: %d\r\n\r\n",
		(int)response.size());
	ns_send(nc, response.data(), response.size());

}
Example #2
0
static void client_handler(struct ns_connection *conn, enum ns_event ev,
                           void *p) {
    struct iobuf *io = &conn->recv_iobuf;
    (void) p;

    if (ev == NS_CONNECT) {
        if (conn->flags & NSF_CLOSE_IMMEDIATELY) {
            printf("%s\n", "Error connecting to server!");
            exit(EXIT_FAILURE);
        }
        printf("%s\n", "Connected to server. Type a message and press enter.");
    } else if (ev == NS_RECV) {
        if (conn->flags & NSF_USER_1) {
            // Received data from the stdin, forward it to the server
            struct ns_connection *c = (struct ns_connection *) conn->user_data;
            ns_send(c, io->buf, io->len);
            iobuf_remove(io, io->len);
        } else {
            // Received data from server connection, print it
            fwrite(io->buf, io->len, 1, stdout);
            iobuf_remove(io, io->len);
        }
    } else if (ev == NS_CLOSE) {
        // Connection has closed, most probably cause server has stopped
        exit(EXIT_SUCCESS);
    }
}
Example #3
0
/*
**  Name:	void ns_reset(dpeth_t *dep)
**  Function:	Resets device.
*/
static void ns_reset(dpeth_t * dep)
{
  int ix;

  /* Stop chip */
  outb_reg0(dep, DP_CR, CR_STP | CR_NO_DMA);
  outb_reg0(dep, DP_RBCR0, 0);
  outb_reg0(dep, DP_RBCR1, 0);
  for (ix = 0; ix < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); ix += 1)
	 /* Do nothing */ ;
  outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST);
  outb_reg0(dep, DP_CR, CR_STA | CR_NO_DMA);
  outb_reg0(dep, DP_TCR, TCR_NORMAL | TCR_OFST);

  /* Acknowledge the ISR_RDC (remote dma) interrupt. */
  for (ix = 0; ix < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); ix += 1)
	 /* Do nothing */ ;
  outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & NOT(ISR_RDC));

  /* Reset the transmit ring. If we were transmitting a packet, we
   * pretend that the packet is processed. Higher layers will
   * retransmit if the packet wasn't actually sent. */
  dep->de_sendq_head = dep->de_sendq_tail = 0;
  for (ix = 0; ix < dep->de_sendq_nr; ix++)
	dep->de_sendq[ix].sq_filled = FALSE;
  ns_send(dep, TRUE, dep->de_send_s);
  return;
}
Example #4
0
static void choose_backend(struct ns_connection *nc) {
  struct http_message hm;
  struct iobuf *io = &nc->recv_iobuf;
  int req_len = ns_parse_http(io->buf, io->len, &hm);

  if (req_len < 0 || (req_len == 0 && io->len >= NS_MAX_HTTP_REQUEST_SIZE)) {
    /* Invalid, or too large request */
    nc->flags |= NSF_CLOSE_IMMEDIATELY;
  } else if (req_len == 0) {
    /* Do nothing, request is not yet fully buffered */
  } else {
    /*
     * Got HTTP request, look which backend to use. Round-robin over the
     * backends with the same uri_prefix and vhost.
     */
    struct ns_str vhost = *ns_get_http_header(&hm, "host");
    const char *vhost_end = vhost.p;
    while(vhost_end < vhost.p + vhost.len &&
          *vhost_end != ':') {
      vhost_end++;
    }
    vhost.len = vhost_end - vhost.p;

    int i, chosen = -1;
    for (i = 0; i < s_num_http_backends; i++) {
      if (has_prefix(&hm.uri, s_http_backends[i].uri_prefix) &&
          matches_vhost(&vhost, s_http_backends[i].vhost) &&
          (chosen == -1 || s_http_backends[i].usage_counter <
           s_http_backends[chosen].usage_counter)) {
        chosen = i;
      }
    }

    if (chosen == -1) {
      /* No backend with given uri_prefix found, bail out */
      ns_printf(nc, "%s%s\r\n", s_error_404, s_content_len_0);
    } else if (s_http_backends[chosen].redirect != 0) {
      ns_printf(nc, "HTTP/1.1 302 Found\r\nLocation: %s\r\n\r\n",
                s_http_backends[chosen].host_port);
      nc->flags |= NSF_SEND_AND_CLOSE;
    } else if ((nc->proto_data = ns_connect(nc->mgr,
               s_http_backends[chosen].host_port, ev_handler)) == NULL) {
      /* Connection to backend failed */
      ns_printf(nc, "%s%s\r\n", s_error_500, s_content_len_0);
    } else {
      /*
       * Forward request to the backend. Note that we can insert extra headers
       * to pass information to the backend.
       * Store backend index as user_data for the backend connection.
       */
      ((struct ns_connection *) nc->proto_data)->proto_data = nc;
      ((struct ns_connection *) nc->proto_data)->user_data =
        (void *) (long) chosen;
      s_http_backends[chosen].usage_counter++;
      ns_send(nc->proto_data, io->buf, io->len);
      iobuf_remove(io, io->len);
    }
  }
}
Example #5
0
static void js_send(struct v7 *v7, struct v7_val *this_obj,
                    struct v7_val *result,
                    struct v7_val **args, int num_args) {
  struct ns_connection *nc = get_nc(this_obj);
  int i;
  (void) v7; (void) result;
  for (i = 0; i < num_args; i++) {
    if (args[i]->type != V7_STR) continue;
    ns_send(nc, args[i]->v.str.buf, args[i]->v.str.len);
  }
}
Example #6
0
static void js_write(struct v7 *v7, struct v7_val *obj,
                     struct v7_val *result,
                     struct v7_val *args, int num_args) {
  int i;
  struct ns_connection *nc = get_nc(obj);
  (void) v7;
  result->type = V7_NUM;
  result->v.num = 0;
  for (i = 0; i < num_args; i++) {
    if (args[i].type != V7_STR) continue;
    ns_send(nc, args[i].v.str.buf, args[i].v.str.len);
  }
}
Example #7
0
static void ev_handler(struct ns_connection *nc, int ev, void *p) {
  struct iobuf *io = &nc->recv_iobuf;
  (void) p;

  switch (ev) {
    case NS_RECV:
      ns_send(nc, io->buf, io->len);  // Echo message back
      iobuf_remove(io, io->len);        // Discard message from recv buffer
      break;
    default:
      break;
  }
}
Example #8
0
static void server_handler(struct ns_connection *nc, enum ns_event ev,
                           void *p) {
    (void) p;
    if (ev == NS_RECV) {
        // Push received message to all ncections
        struct iobuf *io = &nc->recv_iobuf;
        struct ns_connection *c;

        for (c = ns_next(nc->mgr, NULL); c != NULL; c = ns_next(nc->mgr, c)) {
            ns_send(c, io->buf, io->len);
        }
        iobuf_remove(io, io->len);
    }
}
Example #9
0
static void forward_body(struct peer *src, struct peer *dst) {
    struct mbuf *src_io = &src->nc->recv_mbuf;
    if (src->body_sent < src->body_len) {
        size_t to_send = src->body_len - src->body_sent;
        if (src_io->len < to_send) {
            to_send = src_io->len;
        }
        ns_send(dst->nc, src_io->buf, to_send);
        src->body_sent += to_send;
        mbuf_remove(src_io, to_send);
    }
#ifdef DEBUG
    write_log("forward_body %p (ka=%d) -> %p sent %d of %d\n", src->nc,
              src->flags.keep_alive, dst->nc, src->body_sent, src->body_len);
#endif
}
Example #10
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;
  }
}
Example #11
0
/*
**  Name:	void ns_interrupt(dpeth_t * dep)
**  Function:	Handles interrupt.
*/
static void ns_interrupt(dpeth_t * dep)
{
  int isr, tsr;
  int queue;

  while ((isr = inb_reg0(dep, DP_ISR)) != 0) {

	outb_reg0(dep, DP_ISR, isr);
	if (isr & (ISR_PTX | ISR_TXE)) {

		tsr = inb_reg0(dep, DP_TSR);
		if (tsr & TSR_PTX) {
			dep->de_stat.ets_packetT++;
		}
		if (tsr & TSR_COL) dep->de_stat.ets_collision++;
		if (tsr & (TSR_ABT | TSR_FU)) {
			dep->de_stat.ets_fifoUnder++;
		}
		if ((isr & ISR_TXE) || (tsr & (TSR_CRS | TSR_CDH | TSR_OWC))) {
			printf("%s: got send Error (0x%02X)\n", dep->de_name, tsr);
			dep->de_stat.ets_sendErr++;
		}
		queue = dep->de_sendq_tail;

		if (!(dep->de_sendq[queue].sq_filled)) {	/* Hardware bug? */
			printf("%s: transmit interrupt, but not sending\n", dep->de_name);
			continue;
		}
		dep->de_sendq[queue].sq_filled = FALSE;
		if (++queue == dep->de_sendq_nr) queue = 0;
		dep->de_sendq_tail = queue;
		if (dep->de_sendq[queue].sq_filled) {
			ns_start_xmit(dep, dep->de_sendq[queue].sq_size,
				dep->de_sendq[queue].sq_sendpage);
		}
		if (dep->de_flags & DEF_SENDING) {
			ns_send(dep, TRUE, dep->de_send_s);
		}
	}
	if (isr & ISR_PRX) {
		ns_recv(dep, TRUE, 0);
	}
	if (isr & ISR_RXE) {
		printf("%s: got recv Error (0x%04X)\n", dep->de_name, inb_reg0(dep, DP_RSR));
		dep->de_stat.ets_recvErr++;
	}
	if (isr & ISR_CNT) {
		dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
		dep->de_stat.ets_recvErr += inb_reg0(dep, DP_CNTR1);
		dep->de_stat.ets_fifoOver += inb_reg0(dep, DP_CNTR2);
	}
	if (isr & ISR_OVW) {
		printf("%s: got overwrite warning\n", dep->de_name);
	}
	if (isr & ISR_RDC) {
		/* Nothing to do */
	}
	if (isr & ISR_RST) {
		/* This means we got an interrupt but the ethernet
		 * chip is shutdown. We set the flag DEF_STOPPED, and
		 * continue processing arrived packets. When the
		 * receive buffer is empty, we reset the dp8390. */
		printf("%s: network interface stopped\n", dep->de_name);
		dep->de_flags |= DEF_STOPPED;
		break;
	}
  }
  if ((dep->de_flags & (DEF_READING | DEF_STOPPED)) == (DEF_READING | DEF_STOPPED)) {

	/* The chip is stopped, and all arrived packets delivered */
	ns_reset(dep);
	dep->de_flags &= NOT(DEF_STOPPED);
  }
  return;
}