Exemplo n.º 1
0
static void ws_read_cb(evbev_t * bev, void *arg) {
    size_t data_len = 0;

    wshtp_conn_t *conn = (wshtp_conn_t*)arg;

    evbuf_t *in = bufferevent_get_input(bev);

    bufferevent_lock(bev);

    while ( (data_len = evbuffer_get_length(in)) ){
        void *data = evbuffer_pullup(in, data_len);

        ws_frame_t frame;

        size_t nread = ws_parse_frame(data, data_len, &frame);

        if (frame.status == STATUS_OK) {

            if (frame.opcode == OP_TEXT) {
                conn->data.type = WS_DATA_TEXT;
                conn->method = WSHTP_ON_MESSAGE;
            } else if (frame.opcode == OP_BIN) {
                conn->data.type = WS_DATA_BINARY;
                conn->method = WSHTP_ON_MESSAGE;
            } else if (frame.opcode == OP_CLOSE) {
                conn->method = WSHTP_ON_CLOSE;
            }

            if (frame.fin == 0 || frame.opcode == OP_CONT) {
                if (conn->data.ws_frames == NULL) {
                    conn->data.ws_frames = ws_buffer_new();
                }
                ws_buffer_append_data(conn->data.ws_frames, frame.data, frame.payload_len);
            }

            if (conn->method == WSHTP_ON_CLOSE) {
                evbuffer_drain(in, data_len);
            } else {
                evbuffer_drain(in, nread);
            }

            if (frame.fin) {
                if (conn->data.ws_frames) {
                    conn->data.content = ws_buffer_get_data(conn->data.ws_frames, &conn->data.size);
                    ws_buffer_free(conn->data.ws_frames);
                    conn->data.ws_frames = NULL;
                } else {
                    conn->data.content = frame.data;
                    conn->data.size = frame.payload_len;
                }

                bufferevent_unlock(bev);

                wshtp_hooks_call(conn->server, conn->method, conn);

                bufferevent_lock(bev);

                free(conn->data.content);
                conn->data.content = NULL;
                conn->data.size = 0;
            }
        } else {
            break;
        }
    }

    // free fragments
    bufferevent_unlock(bev);
}
Exemplo n.º 2
0
static int ICACHE_FLASH_ATTR http_ws_cgi_execute(http_connection * c){

	NODE_DBG("http_ws_cgi_execute c =%p",c);

	if(!c->handshake_ok)
	{
		int r = http_ws_handle_connect(c);
		if(r==HTTP_WS_CGI_DONE)
			c->cgi.done=1; //mark for destruction
		
		http_transmit(c);
	}
	else{

		if(c->body.data==NULL){

			if(c->state==HTTPD_STATE_WS_DATA_SENT){
				if(data_sent_callback!=NULL)
					data_sent_callback(c);					
			}
			
		}
		else if(c->state==HTTPD_STATE_WS_DATA){

			NODE_DBG("websocket frame size %d",c->body.len);

			ws_frame frame;
			ws_parse_frame(&frame,c->body.data,c->body.len);


			switch(frame.TYPE){

				case WS_INVALID:
					NODE_DBG("\treceived invalid frame");
					break;
				case WS_PING:
					//send ping
					ws_output_frame(&frame,WS_PING,"PING",strlen("PING"));
					ws_write_frame(&frame,ws_output_write_function,c);
					http_transmit(c);
				case WS_CLOSE:
					//send close back
					ws_output_frame(&frame,WS_PING,"\0\0",2);
					ws_write_frame(&frame,ws_output_write_function,c);
					http_transmit(c);
					//mark as done
					c->cgi.done=1;
					break;
				case WS_TEXT:
				case WS_BINARY:
					http_ws_handle_message(c,&frame);
					break;
				case WS_CONTINUATION:
					break; // TODO: Implement continuation logic

			}		


		}
		else if(c->state == HTTPD_STATE_WS_CLIENT_DISCONNECT){

			if(client_disconnected_callback!=NULL)
				client_disconnected_callback(c);
		}

		return 1;

	}

}