コード例 #1
0
void ape_ws_write(ape_socket *socket_client, unsigned char *data,
	size_t len, ape_socket_data_autorelease data_type)
{
	unsigned char payload_head[32] = { 0x81 };
	size_t payload_length = 0;

	if (len <= 125) {
		payload_head[1] = (unsigned char)len & 0x7F;
		
		payload_length = 2;
	} else if (len <= 65535) {
		unsigned short int s = htons(len);
		payload_head[1] = 126;
		memcpy(&payload_head[2], &s, 2);
		
		payload_length = 4;
		
	} else if (len <= 0xFFFFFFFF) {
		unsigned int s = htonl(len);
		payload_head[1] = 127;
		payload_head[2] = 0;
		payload_head[3] = 0;
		payload_head[4] = 0;
		payload_head[5] = 0;
		
		memcpy(&payload_head[6], &s, 4);
		
		payload_length = 10;
	}
	
	printf("Writting WS to %d\n", socket_client->s.fd);
	PACK_TCP(socket_client->s.fd);
		APE_socket_write(socket_client, payload_head, payload_length, APE_DATA_STATIC);
		APE_socket_write(socket_client, data, len, data_type);
	FLUSH_TCP(socket_client->s.fd);
}
コード例 #2
0
/*
	Send queue to socket
*/
int send_raws(subuser *user, acetables *g_ape)
{
	int finish = 1, state = 0;
	struct _raw_pool *pool;
	struct _transport_properties *properties;

	if (user->raw_pools.nraw == 0) {
		return 1;
	}

	PACK_TCP(user->client->fd); /* Activate TCP_CORK */
	
	properties = transport_get_properties(user->user->transport, g_ape);
	
	if (!user->headers.sent) {
		user->headers.sent = 1;
		
		switch(user->user->transport) {
			case TRANSPORT_XHRSTREAMING:
				finish &= http_send_headers(user->headers.content, HEADER_XHR, HEADER_XHR_LEN, user->client, g_ape);
				break;
			case TRANSPORT_SSE_LONGPOLLING:
				finish &= http_send_headers(user->headers.content, HEADER_SSE, HEADER_SSE_LEN, user->client, g_ape);
				break;
			case TRANSPORT_WEBSOCKET:
			case TRANSPORT_WEBSOCKET_IETF:
				break;
			default:
				finish &= http_send_headers(user->headers.content, HEADER_DEFAULT, HEADER_DEFAULT_LEN, user->client, g_ape);
				break;
		}
		
	}
	
	if (properties != NULL && properties->padding.left.val != NULL) {
		finish &= sendbin(user->client->fd, properties->padding.left.val, properties->padding.left.len, 0, g_ape);
	}

	if (user->raw_pools.high.nraw) {
		pool = user->raw_pools.high.rawfoot->prev;
	} else {
		pool = user->raw_pools.low.rawhead;
		state = 1;
	}
	
	if (user->user->transport == TRANSPORT_WEBSOCKET_IETF) {
	    char payload_head[32] = { 0x84 };
	    int payload_size = raws_size(user); /* TODO: fragmentation? */
	    int payload_length = 0;
	    
	    if (payload_size <= 125) {
	        payload_head[1] = (unsigned char)payload_size & 0x7F;
	        payload_length = 2;
	    } else if (payload_size <= 65535) {
	        unsigned short int s = htons(payload_size);
	        payload_head[1] = 126;
	        
	        memcpy(&payload_head[2], &s, 2);
	        
	        payload_length = 4;
	    } else if (payload_size <= 0xFFFFFFFF) {
	        unsigned int s = htonl(payload_size);
	        
	        payload_head[1] = 127;
	        payload_head[2] = 0;
	        payload_head[3] = 0;
	        payload_head[4] = 0;
	        payload_head[5] = 0;
	        
            memcpy(&payload_head[6], &s, 4);

	        payload_length = 10;
	    }
        
        finish &= sendbin(user->client->fd, payload_head, payload_length, 0, g_ape);

	}
	finish &= sendbin(user->client->fd, "[", 1, 0, g_ape);
		
	while (pool->raw != NULL) {
		struct _raw_pool *pool_next = (state ? pool->next : pool->prev);

		finish &= sendbin(user->client->fd, pool->raw->data, pool->raw->len, 0, g_ape);

		if ((pool_next != NULL && pool_next->raw != NULL) || (!state && user->raw_pools.low.nraw)) {
			finish &= sendbin(user->client->fd, ",", 1, 0, g_ape);
		} else {
			finish &= sendbin(user->client->fd, "]", 1, 0, g_ape);
			
			if (properties != NULL && properties->padding.right.val != NULL) {
				finish &= sendbin(user->client->fd, properties->padding.right.val, properties->padding.right.len, 0, g_ape);
			}
		}
		
		free_raw(pool->raw);
		pool->raw = NULL;
		
		pool = pool_next;
		
		if ((pool == NULL || pool->raw == NULL) && !state) {
			pool = user->raw_pools.low.rawhead;
			state = 1;
		}
	}
	
	user->raw_pools.high.nraw = 0;
	user->raw_pools.low.nraw = 0;
	user->raw_pools.nraw = 0;
	
	user->raw_pools.high.rawfoot = user->raw_pools.high.rawhead;
	user->raw_pools.low.rawfoot = user->raw_pools.low.rawhead;
	
	FLUSH_TCP(user->client->fd);
	
	return finish;
}
コード例 #3
0
static void process_websocket_frame(ape_socket *co, acetables *g_ape)
{
    ape_buffer *buffer = &co->buffer_in;
    websocket_state *websocket = co->parser.data;
    ape_parser *parser = &co->parser;
    
    unsigned char *pData;
    
    for (pData = (unsigned char *)&buffer->data[websocket->offset]; websocket->offset < buffer->length; websocket->offset++, pData++) {
        switch(websocket->step) {
            case WS_STEP_KEY:
                /* Copy the xor key (32 bits) */
                websocket->key.val[websocket->key.pos] = *pData;
                if (++websocket->key.pos == 4) {
                    websocket->step = WS_STEP_DATA;
                }
                break;
            case WS_STEP_START:
                /* Contain fragmentaiton infos & opcode (+ reserved bits) */
                websocket->frame_payload.start = *pData;

                websocket->step = WS_STEP_LENGTH;
                break;
            case WS_STEP_LENGTH:
                /* Check for MASK bit */
                if (!(*pData & 0x80)) {
                    return;
                }
                switch (*pData & 0x7F) { /* 7bit length */
                    case 126:
                        /* Following 16bit are length */
                        websocket->step = WS_STEP_SHORT_LENGTH;
                        break;
                    case 127:
                        /* Following 64bit are length */
                        websocket->step = WS_STEP_EXTENDED_LENGTH;
                        break;
                    default:
                        /* We have the actual length */
                        websocket->frame_payload.extended_length = *pData & 0x7F;
                        websocket->step = WS_STEP_KEY;
                        break;
                }
                break;
            case WS_STEP_SHORT_LENGTH:
                memcpy(((char *)&websocket->frame_payload)+(websocket->frame_pos), 
                        pData, 1);
                if (websocket->frame_pos == 3) {
                    websocket->frame_payload.extended_length = ntohs(websocket->frame_payload.short_length);
                    websocket->step = WS_STEP_KEY;
                }
                break;
            case WS_STEP_EXTENDED_LENGTH:
                memcpy(((char *)&websocket->frame_payload)+(websocket->frame_pos),
                        pData, 1);
                if (websocket->frame_pos == 9) {
                    websocket->frame_payload.extended_length = ntohl(websocket->frame_payload.extended_length >> 32);
                    websocket->step = WS_STEP_KEY;
                }        
                break;
            case WS_STEP_DATA:
                if (websocket->data_pos == 0) {
                    websocket->data_pos = websocket->offset;
                }
                
                *pData ^= websocket->key.val[(websocket->frame_pos - websocket->data_pos) % 4];

                if (--websocket->frame_payload.extended_length == 0) {
                    unsigned char saved;
                    
                    websocket->data = &buffer->data[websocket->data_pos];
                    websocket->step = WS_STEP_START;
                    websocket->frame_pos = -1;
                    websocket->frame_payload.extended_length = 0;
                    websocket->data_pos = 0;
                    websocket->key.pos = 0;

                    switch(websocket->frame_payload.start & 0x0F) {
                        case 0x8:
                        {
                            /*
                              Close frame
                              Reply by a close response
                            */
                            char payload_head[2] = { 0x88, 0x00 };
                            sendbin(co->fd, payload_head, 2, 0, g_ape);
                            return;
                        }
                        case 0x9:
                        {
                            int body_length = &buffer->data[websocket->offset+1] - websocket->data;
                            char payload_head[2] = { 0x8a, body_length & 0x7F };
                            
                            /* All control frames MUST be 125 bytes or less */
                            if (body_length > 125) {
                                payload_head[0] = 0x88;
                                payload_head[1] = 0x00;      
                                sendbin(co->fd, payload_head, 2, 1, g_ape);
                                return;
                            }
                            PACK_TCP(co->fd);
                            sendbin(co->fd, payload_head, 2, 0, g_ape);
                            if (body_length) {
                                sendbin(co->fd, websocket->data, body_length, 0, g_ape);
                            }
                            FLUSH_TCP(co->fd);
                            break;
                        }
                        case 0xA: /* Never called as long as we never ask for pong */
                            break;
                        default:
                            /* Data frame */
                            saved = buffer->data[websocket->offset+1];
                            buffer->data[websocket->offset+1] = '\0';
                            parser->onready(parser, g_ape);
                            buffer->data[websocket->offset+1] = saved;                            
                            break;
                    }
                    
                    if (websocket->offset+1 == buffer->length) {
                        websocket->offset = 0;
                        buffer->length = 0;
                        websocket->frame_pos = 0;
                        websocket->key.pos = 0;
                        return;
                    }
                }
                break;
            default:
                break;
        }
        websocket->frame_pos++;
    }
コード例 #4
0
ファイル: handle_http.c プロジェクト: Vinz3056/APE_Server
subuser *checkrecv(ape_socket *co, acetables *g_ape)
{
	unsigned int op;
	http_state *http = co->parser.data;
	subuser *user = NULL;
	clientget cget;
	
	if (http->host == NULL) {
		shutdown(co->fd, 2);
		return NULL;
	}
	
	if (gettransport(http->uri) == TRANSPORT_WEBSOCKET) {
		char *origin = get_header_line(http->hlines, "Origin");
		websocket_state *websocket;
		if (origin == NULL) {
			shutdown(co->fd, 2);
			return NULL;
		}
		
		PACK_TCP(co->fd);
		sendbin(co->fd, CONST_STR_LEN(WEBSOCKET_HARDCODED_HEADERS), 0, g_ape);
		sendbin(co->fd, CONST_STR_LEN("WebSocket-Origin: "), 0, g_ape);
		sendbin(co->fd, origin, strlen(origin), 0, g_ape);
		sendbin(co->fd, CONST_STR_LEN("\r\nWebSocket-Location: ws://"), 0, g_ape);
		sendbin(co->fd, http->host, strlen(http->host), 0, g_ape);
		sendbin(co->fd, http->uri, strlen(http->uri), 0, g_ape);
		sendbin(co->fd, CONST_STR_LEN("\r\n\r\n"), 0, g_ape);
		FLUSH_TCP(co->fd);
		
		co->parser = parser_init_stream(co);
		websocket = co->parser.data;
		websocket->http = http; /* keep http data */
		
		return NULL;
	}

	if (http->data == NULL) {
		sendbin(co->fd, HEADER_DEFAULT, HEADER_DEFAULT_LEN, 0, g_ape);
		sendbin(co->fd, CONST_STR_LEN(CONTENT_NOTFOUND), 0, g_ape);
		
		safe_shutdown(co->fd, g_ape);
		return NULL;
	}
	
	cget.client = co;
	cget.ip_get = co->ip_client;
	cget.get = http->data;
	cget.host = http->host;
	cget.hlines = http->hlines;
	
	op = checkcmd(&cget, gettransport(http->uri), &user, g_ape);

	switch (op) {
		case CONNECT_SHUTDOWN:
			safe_shutdown(co->fd, g_ape);			
			break;
		case CONNECT_KEEPALIVE:
			break;
	}
	
	return user;
}