Exemple #1
0
void nbuf_allocq(ndesc_t *nd, char *s, int sl)
{
	check_ndesc(nd);
	nbuf_t **q = &nd->q, **q_head = &nd->q_head;
	nbuf_t *nb;
	bool ovfl;
	static int id;
	
	assert(s && sl);
	nb = nbuf_malloc();
	//assert(nd->mc);
	nb->mc = nd->mc;
	nb->buf = (char*) wrx_malloc("nbuf:buf", sl);
	memcpy(nb->buf, s, sl);
	nb->len = sl;
	nb->done = FALSE;
	nb->dequeued = FALSE;
	nb->ttl = nd->ttl;
	if (nd->dbug) nb->id = id++;
	ovfl = nbuf_enqueue(nd, nb);
	if (nd->dbug) printf("A%d ", nb->id);
	if (nd->dbug) nbuf_dumpq(nd);
	
	check_nbuf(nb);
	if (ovfl) {
		wrx_free("nbuf:buf", nb->buf);
		nbuf_free(nb);
	}
}
Exemple #2
0
static const char* edata(const char *uri, size_t *size, char **free_buf) {
	const char* data = NULL;
	
#ifdef EDATA_EMBED
	// the normal background daemon loads files from in-memory embedded data
	data = edata_embed(uri, size);
#endif

	// some large, seldom-changed files are always loaded from memory
	if (!data) data = edata_always(uri, size);

#ifdef EDATA_DEVEL
	// to speed edit-copy-compile-debug development, load the files from the local filesystem
	static bool init;
	if (!init) {
		scall("chdir web", chdir("web"));
		init = true;
	}

	// try as a local file
	if (!data) {
		int fd = open(uri, O_RDONLY);
		if (fd >= 0) {
			struct stat st;
			fstat(fd, &st);
			*size = st.st_size;
			data = (char *) wrx_malloc("file", *size);
			*free_buf = (char *) data;
			ssize_t rsize = read(fd, (void *) data, *size);
			assert(rsize == *size);
			close(fd);
		}
	}
#endif

	return data;
}
Exemple #3
0
static nbuf_t *nbuf_malloc()
{
	nbuf_t *nb;
	
#ifdef NBUF_STATIC_ALLOC
	lock_enter(&nbuf_lock);
		int i;
		for (i=0; i<NNBUF; i++) {
			nb = &nbuf[i];
			if (nb->isFree)
				break;
		}
		if (i == NNBUF) panic("out of nbufs");
	lock_leave(&nbuf_lock);
#else
	nb = (nbuf_t*) wrx_malloc("nbuf", sizeof(nbuf_t));
#endif
	memset(nb, 0, sizeof(nbuf_t));
	nb->magic = NB_MAGIC;
	nb->magic_b = NBUF_MAGIC_B;
	nb->magic_e = NBUF_MAGIC_E;
	check_nbuf(nb);
	return nb;
}
Exemple #4
0
static int request(struct mg_connection *mc) {
	size_t edata_size=0;
	const char *edata_data;
	char *free_buf = NULL;

	if (mc->is_websocket) {
		// This handler is called for each incoming websocket frame, one or more
		// times for connection lifetime.
		char *s = mc->content;
		int sl = mc->content_len;
		//printf("WEBSOCKET: len %d uri <%s>\n", sl, mc->uri);
		if (sl == 0) {
			//printf("----KA %d\n", mc->remote_port);
			return MG_TRUE;	// keepalive?
		}
		
		conn_t *c = rx_server_websocket(mc);
		if (c == NULL) return MG_FALSE;
		if (c->stop_data) return MG_FALSE;
		
		s[sl]=0;
		//printf("WEBSOCKET: %d <%s> ", sl, s);
		nbuf_allocq(&c->w2a, s, sl);
		
		if (mc->content_len == 4 && !memcmp(mc->content, "exit", 4)) {
			//printf("----EXIT %d\n", mc->remote_port);
			return MG_FALSE;
		} else {
			return MG_TRUE;
		}
	} else {
		if (strcmp(mc->uri, "/") == 0) mc->uri = "index.html"; else
		if (mc->uri[0] == '/') mc->uri++;
		
		char *ouri = (char *) mc->uri;
		char *uri = ouri;
		bool free_uri = FALSE;
		
		if (strncmp(ouri, "wrx/", 4) == 0) {
			uri = (char *) &mc->uri[4];
		} else {
			user_iface_t *ui = find_ui(mc->local_port);
			// should never not find match since we only listen to ports in ui table
			assert(ui);
			asprintf(&uri, "%s/%s", ui->name, ouri);
			free_uri = TRUE;
		}
		//printf("---- HTTP: uri %s (%s)\n", ouri, uri);

		// try as file from in-memory embedded data
		edata_data = edata(uri, &edata_size, &free_buf);
		
		// try as request from browser
		if (!edata_data) {
			free_buf = (char*) wrx_malloc("req", NREQ_BUF);
			edata_data = rx_server_request(mc, free_buf, &edata_size);	// mc->uri is ouri without ui->name prefix
			if (!edata_data) { wrx_free("req", free_buf); free_buf = NULL; }
		}

		if (!edata_data) {
			printf("unknown URL: %s (%s) %s\n", ouri, uri, mc->query_string);
			return MG_FALSE;
		}
		
		// for index.html process %[substitution]
		if (strcmp(ouri, "index.html") == 0) {
			static bool index_init;
			static char *index_html, *index_buf;
			static size_t index_size;

#ifdef EDATA_EMBED
			if (!index_init) {		// only have to do once
#else
			if (true) {		// file might change anytime during development
#endif
				if (!index_buf) index_buf = (char*) wrx_malloc("index_buf", edata_size*3/2);
				char *cp = (char*) edata_data, *np = index_buf, *pp;
				int i, cl, sl, nl=0, pl;

				for (cl=0; cl < edata_size;) {
					if (*cp == '%' && *(cp+1) == '[') {
						cp += 2; cl += 2; pp = cp; pl = 0;
						while (*cp != ']' && cl < edata_size) { cp++; cl++; pl++; }
						cp++; cl++;
						for (i=0; i < ARRAY_LEN(index_html_params); i++) {
							index_html_params_t *ip = &index_html_params[i];
							if (strncmp(pp, ip->param, pl) == 0) {
								sl = strlen(ip->value);
								strcpy(np, ip->value); np += sl;
								break;
							}
						}
						if (i == ARRAY_LEN(index_html_params)) {
							// not found, put back original
							strcpy(np, "%["); np += 2;
							strncpy(np, pp, pl); np += pl;
							*np++ = ']';
						}
					} else {
						*np++ = *cp++; cl++;
					}
				}
				
				index_html = index_buf;
				index_size = np - index_buf;
				index_init = true;
			}
			edata_data = index_html;
			edata_size = index_size;
		}

		//printf("DATA: %s %d ", mc->uri, (int) edata_size);
		mg_send_header(mc, "Content-Type", mg_get_mime_type(mc->uri, "text/plain"));
		mg_send_data(mc, edata_data, edata_size);
		
		if (free_uri) free(uri);
		if (free_buf) wrx_free("req", free_buf);
		
		http_bytes += edata_size;
		return MG_TRUE;
	}
}

static int ev_handler(struct mg_connection *mc, enum mg_event ev) {
  int r;
  
  //printf("ev_handler %d:%d len %d ", mc->local_port, mc->remote_port, (int) mc->content_len);
  if (ev == MG_REQUEST) {
  	//printf("MG_REQUEST: URI:%s query:%s\n", mc->uri, mc->query_string);
    r = request(mc);
    //printf("\n");
    return r;
  } else
  if (ev == MG_AUTH) {
  	//printf("MG_AUTH\n");
    return MG_TRUE;
  } else {
  	//printf("MG_OTHER\n");
    return MG_FALSE;
  }
}