Exemplo n.º 1
0
static void after_queue_work(uv_work_t* req, int status)
{
	automem_t mem;
	webqueuework_t * qwork = container_of(req, webqueuework_t, work);
	rbnode_t * n = rb_first(&qwork->request->headers);

	automem_init(&mem, 256);
	if (qwork->conn->proto == WEB_PROTO_HTTP) {
		if (qwork->status == 101 && qwork->request->upgrade) {
			webheader_t k;
			rbnode_t * n;
			const char * ver = NULL, *key = NULL;
			k.key = "Sec-WebSocket-Version";
			if (n = rb_find(&qwork->request->headers, &k.n)) ver = container_of(n, webheader_t, n)->val;
			k.key = "Sec-WebSocket-Key";
			if (n = rb_find(&qwork->request->headers, &k.n)) key = container_of(n, webheader_t, n)->val;
			if (NULL != key && NULL != ver) {
				ws_do_handeshake(&mem, key, strlen(key));
				qwork->conn->proto = WEB_PROTO_WEBSOCKET;
				if (uv_is_active((uv_handle_t *)&qwork->conn->conn)) {
					wsparser_init(&qwork->conn->ws_parser, 13, 20480);
					qwork->conn->request = webrequest_get(qwork->request);//引用起来,不丢掉.
				}
				goto contents_prepare_final;
			}
		}
		rbnode_t * n = rb_first(&qwork->headers);
		automem_init_headers(&mem, qwork->status, qwork->flags);
		while (n) {
			webheader_t * h = container_of(n, webheader_t, n);
			automem_append_voidp(&mem, h->key, strlen(h->key));
			automem_append_voidp(&mem, ": ", 2);
			automem_append_voidp(&mem, h->val, strlen(h->val));
			automem_append_voidp(&mem, "\r\n", 2);
			n = rb_next(n);
		}
		automem_append_contents(&mem, qwork->mem.pdata, qwork->mem.size);

	}
	else if(qwork->conn->proto==WEB_PROTO_WEBSOCKET) {
		wsframe_make(&mem, WS_TEXT_FRAME, 0, qwork->mem.pdata, qwork->mem.size);
	}
contents_prepare_final:
	if (0 != webconn_sendmem(qwork->conn, &mem)) {
		automem_uninit(&mem);
	}
	webqueuework_free(qwork);
}
Exemplo n.º 2
0
Arquivo: automem.c Projeto: cosim/uvx
int automem_append_field_int(automem_t* pmem, const char * field, unsigned int f_len, int val)
{
	char intVal[20];int slen;

	automem_append_voidp(pmem, field, f_len);
	_itoa(val, intVal,10);
	slen = strlen(intVal);

	automem_ensure_newspace(pmem, slen + 4);
	pmem->pdata[pmem->size++]='=';
	pmem->pdata[pmem->size++]='"';
	automem_append_voidp(pmem, intVal, slen);
	pmem->pdata[pmem->size++]='"';
	pmem->pdata[pmem->size++]=' ';
	return pmem->size;
}
Exemplo n.º 3
0
Arquivo: automem.c Projeto: cosim/uvx
int automem_append_field_fast(automem_t* pmem, const char * field, unsigned int f_len, const char * val,unsigned int v_len)
{
	if(NULL == val) return pmem->size;
	if(0 == v_len) v_len = strlen(val);
	if(0 == v_len) return pmem->size;

	automem_append_voidp(pmem, field, f_len);
	automem_ensure_newspace(pmem, v_len + 5);


	pmem->pdata[pmem->size++]='=';
	pmem->pdata[pmem->size++]='"';
	automem_append_voidp(pmem, val, v_len);
	pmem->pdata[pmem->size++]='"';
	pmem->pdata[pmem->size++]=' ';

	return pmem->size;
}
Exemplo n.º 4
0
/*
	构造一个或者一堆的Frame 。
	//服务器端发往客户端的数据 不允许使用 mask
*/
void wsframe_make(automem_t * mem,enum wsFrameType opcode, int _mask, unsigned char * payload, size_t len) {
	struct wsFrameHeader * fh; 
	uint8_t mask[4];
	size_t i;
	srand((unsigned int)time(NULL));
	
	automem_ensure_newspace(mem, len + 20);
	fh = (struct wsFrameHeader * )(&mem->pdata[mem->size]);

	fh->fin = 1;
	fh->opcode = opcode;
	fh->rsv13 = 0;
	fh->mask = 0;
	mem->size += 2;
	if (len < 126) {
		fh->plen = (uint8_t)len;	
	}
	else if (len <= 0xFFFF) {
		uint16_t nlen = SWAP_U16(len);
		fh->plen = 126;
		automem_append_voidp(mem, &nlen, 2);
	}
	else {
		uint64_t nlen = SWAP_U64(len);
		fh->plen = 127;
		automem_append_voidp(mem, &nlen, sizeof(uint64_t));
	}
	if (payload && len > 0){
		if (_mask) {
			fh->mask = 1;
			mask[0] = rand() % 256; mask[1] = rand() % 256; mask[2] = rand() % 256; mask[3] = rand() % 256;
			automem_append_voidp(mem, mask, 4);

			for (i = 0; i < len; i++) {
				mem->pdata[mem->size++] = payload[0] ^ mask[i % 4];
			}
		}
		else {
			automem_append_voidp(mem, payload, len);
		}
	}
}
Exemplo n.º 5
0
int ws_do_handeshake(automem_t * mem, char * key, int lkey)
{
	char * sec;
	char sha_out[20], base64_out[40];
	size_t base64_len = sizeof(base64_out);

	if (0 == lkey) return -1;
	sec = malloc(lkey + sizeof(secret));

	strcpy(sec, key);
	strcpy(sec + lkey, secret);

	sha1(sec, lkey + sizeof(secret) - 1, sha_out);

	base64_encode(base64_out, &base64_len, sha_out, 20);
	automem_init(mem, 256);
	automem_append_voidp(mem, SWITCH_WEBSOCKET_PROTOCOL, sizeof(SWITCH_WEBSOCKET_PROTOCOL) - 1);
	automem_append_voidp(mem, base64_out, base64_len);
	automem_append_voidp(mem, "\r\n\r\n", 4);
	free(sec);
	return 0;
}
Exemplo n.º 6
0
static void webrequest_threadproc(uv_work_t * req)
{
	int ref = LUA_NOREF,sess_ref = LUA_NOREF;
	automem_t mem;
	webqueuework_t * qwork = container_of(req, webqueuework_t, work);
	
	lua_State * L = luaL_newstate();

	qwork->flags = qwork->conn->flags;
	luaL_openlibs(L);
	ref = lua_pushwebctx(L, qwork);
	sess_ref = luasession_init(L,qwork);
	automem_init(&mem,100);
	automem_append_voidp(&mem, "require(\"", sizeof("require(\"") - 1);
	automem_append_voidp(&mem, qwork->request->file, strlen(qwork->request->file));

	switch (qwork->conn->proto) {
	case WEB_PROTO_HTTP:
		automem_append_voidp(&mem, "\"):main()", sizeof("\"):main()"));
		break;
	case WEB_PROTO_WEBSOCKET:
		automem_append_voidp(&mem, "\"):websocket()", sizeof("\"):websocket()"));
		break;
	}
	luaL_dostring(L, mem.pdata);
	if (LUA_TSTRING == lua_type(L, -1)) {
		size_t len;
		const char * err = lua_tolstring(L, -1, &len);
		
		qwork->status = 500;
		automem_append_voidp(&qwork->mem, err, len);
	}

	automem_uninit(&mem);
	luaL_unref(L,LUA_REGISTRYINDEX, ref);
	lua_close(L);
}
Exemplo n.º 7
0
// 向客户端输出内容.
static int lua_webctx_write(lua_State * L) {
	int i,argc = lua_gettop(L),t;
	const char * s;
	webqueuework_t * qwork = (lua_rawgeti(L, LUA_REGISTRYINDEX, WEBCTX_REF), lua_touserdata(L, -1));

	for (i = 1; i <= argc; i++) {
		size_t len;
		t = lua_type(L, i);
		switch (t) {
		case LUA_TNIL:
		case LUA_TNONE:
			break;
		default:
			s = lua_tolstring(L, i, &len);
			automem_append_voidp(&qwork->mem, s, (unsigned int)len);
			break;
		}
	}
	return 0;
}
Exemplo n.º 8
0
static void lua_tpl_expand_variables(lua_State * L, automem_t * mem, int bufsize) {
    if(lua_istable(L, 3)) {
        const char * key ;
        automem_init(mem, bufsize + 10240);
        lua_pushnil(L);
        automem_append_voidp(mem, "local _ARGS_= ...\n",sizeof("local _ARGS_= ...\n")-1);
        while(lua_next(L, 3)) {
            // -1 value -2 key
            if(lua_isstring(L, -2)) {
                size_t lkey;
                if(NULL != (key = lua_tolstring(L, -2, &lkey))) {
                    automem_append_voidp(mem, "local ",sizeof("local ")-1);
                    automem_append_voidp(mem, key, lkey);
                    automem_append_voidp(mem, "=_ARGS_[\"",sizeof("=_ARGS_[\"")-1);
                    automem_append_voidp(mem, key, lkey);
                    automem_append_voidp(mem, "\"]\n", sizeof("\"]\n")-1);
                }
            }
            lua_pop(L, 1);
        }
    } else
        automem_init(mem, bufsize + 20);
}
Exemplo n.º 9
0
void wsparser_pushdata(wsparser_t * parser, unsigned char * data, uint32_t size, wsparser_onhandler handler, void * eParam)
{
	unsigned char *p = data;
	uint32_t i;
	if (parser->buf.size > 0) {
		automem_append_voidp(&parser->buf, data, size);
		data = parser->buf.pdata;
		size = parser->buf.size;
	}

	while (parser->offset < size) {
		switch (parser->st) {
		case WS_STATE_OPCODE:
			if (size - parser->offset > 2) {
				struct wsFrameHeader * fh = (struct wsFrameHeader *)&data[parser->offset];
				parser->fin = fh->fin;
				parser->mask = fh->mask;
				parser->opcode = fh->opcode==WS_CONTINUATION_FRAME? parser->opcode: fh->opcode;
				parser->offset += 2;
				parser->st = WS_STATE_PLEN; 
				printf("OpCode = %d, Fin=%d\n", parser->opcode,parser->fin);
				switch (fh->plen) {
				case 126:
					parser->st = WS_STATE_PLEN;
					break;
				case 127:
					parser->st = WS_STATE_PLLEN;
					break;
				default:
					parser->len = fh->plen;
					parser->st = parser->mask ? WS_STATE_MASK : WS_STATE_PAYLOAD;
					break;
				}
				if (WS_PING_FRAME == parser->opcode) {
					handler(parser, NULL, eParam);
				}

			}
			break;
		case WS_STATE_PLEN:
			if (size - parser->offset < 2) goto wsparser_pushdata_final;
			parser->len = SWAP_U16(*(uint16_t *)&data[parser->offset]);
			parser->offset += 2;
			parser->st = parser->mask ? WS_STATE_MASK : WS_STATE_PAYLOAD;
			break;
		case WS_STATE_PLLEN:
			if (size - parser->offset < 8) goto wsparser_pushdata_final;
			parser->len = SWAP_U64(*(uint64_t *)&data[parser->offset]);
#if defined(_DEBUG)
			printf("size = %lld", parser->len);
#endif
			parser->offset += 8;
			parser->st = parser->mask ? WS_STATE_MASK : WS_STATE_PAYLOAD;
			break;
		case WS_STATE_MASK:
			if (size - parser->offset < 4) goto wsparser_pushdata_final;
			memcpy(parser->msk_bytes, &data[parser->offset], 4);
			parser->offset += 4;
			parser->st = WS_STATE_PAYLOAD;
			break;
		case WS_STATE_PAYLOAD:
			if (size - parser->offset < parser->len) goto wsparser_pushdata_final;
			//处理帧数据
			if (parser->mask) {
				automem_t * m = &parser->payload;
				automem_ensure_newspace(m, parser->len);
				for (i = 0; i < parser->len; i++) {
					m->pdata[m->size++] = data[parser->offset+i] ^ parser->msk_bytes[i % 4];
				}
			}
			if (parser->fin == 1) {
				wsFrame * f = malloc(sizeof(wsFrame));
				f->len = parser->payload.size;
				f->opcode = parser->opcode;
				f->pdata = f->len > 0 ? parser->payload.pdata : NULL;

				handler(parser, f, eParam);
				if (f->len){
					parser->payload.pdata = NULL;
					parser->payload.size = parser->payload.buffersize = 0;
					automem_init(&parser->payload, 2048);
				}
			}

			parser->offset += (uint32_t)parser->len;
			parser->st = WS_STATE_OPCODE;
			break;
		}
	}
wsparser_pushdata_final:
	
	if (size > parser->offset) {
		if (data != parser->buf.pdata) {
			automem_append_voidp(&parser->buf, data + parser->offset, size - parser->offset);//将未用完的加入到 buf.
			parser->offset = 0;
		}
	}
	else if (size <= parser->offset) {
		if (data == parser->buf.pdata) {

		}
		if (parser->buf.buffersize > parser->maxsize)
			automem_clean(&parser->buf, parser->maxsize);
		else
			automem_reset(&parser->buf);
		parser->offset = 0;
	}

	return;
}
Exemplo n.º 10
0
Arquivo: automem.c Projeto: cosim/uvx
int automem_append_field(automem_t* pmem, const char * field, unsigned int f_len, const char * val)
{
	const char * p = val;
	char c;
	unsigned int t  = 4, sz = 0;
	if(NULL == val)return pmem->size;
	while(c = *p++)
	{
		switch(c)
		{
		case '&': // 5 &amp;
			t+=5;break;
		case '<': // 4 &lt;
			t+=4;break;
		case '>': // 4 &gt;
			t+=4;break;
		case '"': // 6 &quot;
			t+=6;break;
		case '\'': // 6 &apos;
			t+=6;break;
		default:
			t++;
		}
	}
	automem_append_voidp(pmem, field, f_len);
	automem_ensure_newspace(pmem, t);

	sz = pmem->size;
	pmem->pdata[sz++]='=';
	pmem->pdata[sz++]='"';
	p = val;

	while(c = *p++)
	{
		switch(c)
		{
		case '&': // 5 &amp;
			*(int*)(pmem->pdata+sz) = *(int*)"&amp";
			sz+=sizeof(int);
			pmem->pdata[sz++]=';';
			break;
		case '<': // 4 &lt;
			*(int*)(pmem->pdata+sz) = *(int*)"&lt;";
			sz+=sizeof(int);
			break;
		case '>': // 4 &gt;
			*(int*)(pmem->pdata+sz) = *(int*)"&gt;";
			sz+=sizeof(int);
			break;
		case '"': // 6 &quot;
			*(int*)(pmem->pdata+sz) = *(int*)"&quo";
			sz+=sizeof(int);
			*(short*)(pmem->pdata+sz) = *(short*)"t;";
			sz+=sizeof(short);
			break;
		case '\'': // 6 &apos;
			*(int*)(pmem->pdata+sz) = *(int*)"&apo";
			sz+=sizeof(int);
			*(short*)(pmem->pdata+sz) = *(short*)"s;";
			sz+=sizeof(short);
			break;
		default:
			pmem->pdata[sz++]=c;
		}
	}
	*(short*)(pmem->pdata+sz) = *(short*)"\" ";
	sz+=sizeof(short);
	pmem->size = sz;

	return sz;
}
Exemplo n.º 11
0
Arquivo: automem.c Projeto: cosim/uvx
void automem_append_byte(automem_t* pmem, unsigned char c)
{
	automem_append_voidp(pmem, &c, sizeof(unsigned char));
}
Exemplo n.º 12
0
Arquivo: automem.c Projeto: cosim/uvx
void automem_append_char(automem_t* pmem, char c)
{
	automem_append_voidp(pmem, &c, sizeof(char));
}
Exemplo n.º 13
0
Arquivo: automem.c Projeto: cosim/uvx
void automem_append_pchar(automem_t* pmem, char* n)
{
	automem_append_voidp(pmem, &n, sizeof(char*));
}
Exemplo n.º 14
0
Arquivo: automem.c Projeto: cosim/uvx
void automem_append_int(automem_t* pmem, int n)
{
	automem_append_voidp(pmem, &n, sizeof(int));
}
Exemplo n.º 15
0
static void lua_tpl_compile_local(lua_State * L, automem_t * mem, const char * buf,int lbuf) {
    int state = tpl_state_normal, i = 0;
    register const char * sbuf;
    char c;
    size_t lcmd = sizeof("_") -1,
           lprefix = sizeof("([[")-1,
           lsuffix = sizeof("]])")-1;

    const char * cmd = "_(",
                 * ecmd = ")",
                   * prefix = "([[",
                     * suffix = "]])";

    if(lua_isstring(L, 4))
        cmd =luaL_checklstring(L, 4, &lcmd);

    if(lua_isstring(L, 5))
        prefix =luaL_checklstring(L, 5, &lprefix);

    if(lua_isstring(L, 6))
        suffix =luaL_checklstring(L, 6, &lsuffix);


    sbuf = buf;
    while(i < lbuf) {
        c = buf[i];
        switch (state)
        {
        case tpl_state_normal:
            switch(c) {
            case '{':
                state = tpl_state_scode_1;
                break;
            }
            break;
        case tpl_state_scode_1:
            switch(c) {
            case '#':
                state =tpl_state_code;
                append_end_stringfield(mem,sbuf, &buf[i] - sbuf-1);
                sbuf = &buf[i+1];
                break;
            default:
                state = tpl_state_normal;
                break;
            }
            break;
        case tpl_state_code:
            switch(c) {
            case '#':
                state = tpl_state_ecode_1;
                break;
            }
        case tpl_state_ecode_1:
            switch(c) {
            case '}':
                automem_append_voidp(mem,sbuf, &buf[i] - sbuf-1);
                automem_append_byte(mem,'\n');
                sbuf = &buf[i+1];
                state = tpl_state_normal;
                break;
            default:
                state=tpl_state_code;
            }
        default:
            break;
        }
        i++;
    }
    if(tpl_state_normal == state) {
        append_end_stringfield(mem,sbuf, &buf[i] - sbuf);
    }
}