Exemple #1
0
int bb_socketio_message(struct bb_session *bbs, char *buf, size_t len) {

    if (bbs->sio_session) bbs = bbs->sio_session;

    if (len == 3 && buf[1] == ':' && buf[2] == ':') return 0;
    char *sio_body = find_third_colon(buf, len);
    if (!sio_body) return -1;
    size_t sio_len = len - (sio_body-buf);
    // forward socket.io message to the right session
    switch(buf[0]) {
    case '3':
        bb_zmq_send_msg(bbs->dealer, bbs, (char *) &bbs->uuid_part1, BB_UUID_LEN, "socket.io/msg", 13, sio_body, sio_len);
        break;
    case '4':
        bb_zmq_send_msg(bbs->dealer, bbs, (char *) &bbs->uuid_part1, BB_UUID_LEN, "socket.io/json", 14, sio_body, sio_len);
        break;
    case '5':
        bb_zmq_send_msg(bbs->dealer, bbs, (char *) &bbs->uuid_part1, BB_UUID_LEN, "socket.io/event", 15, sio_body, sio_len);
        break;
    default:
        fprintf(stderr,"SOCKET.IO MESSAGE TYPE: %c\n", buf[0]);
        return -1;
    }
    return 0;
}
Exemple #2
0
static void bb_session_clear(struct bb_session *bbs) {
	int i;
	struct bb_connection *bbc = bbs->connection;

	// remove the session from the hash table
        bb_sht_remove(bbs);
                struct bb_session_request *bbsr = bbs->requests_head;
                while(bbsr) {
                        // in spdy mode, the first header is empty
                        for(i=bbc->spdy;i<=bbsr->header_pos;i++) {
                                free(bbsr->headers[i].key);
                                free(bbsr->headers[i].value);
                        }
                        if (bbsr->uwsgi_buf) {
                                free(bbsr->uwsgi_buf);
                        }
                        if (bbsr->websocket_message_queue) {
                                free(bbsr->websocket_message_queue);
                        }
                        struct bb_session_request *tmp_bbsr = bbsr;
                        bbsr = bbsr->next;
                        free(tmp_bbsr);
                }

                // if linked to a dealer, send a 'end' message
                if (bbs->dealer) {
                        bb_zmq_send_msg(bbs->dealer->identity, bbs->dealer->len, (char *) &bbs->uuid_part1, BB_UUID_LEN, "end", 3, "", 0);
                }

}
Exemple #3
0
static int bb_session_headers_complete(http_parser *parser) {
        //printf("headers parsed\n");
        struct bb_session_request *bbsr = (struct bb_session_request *) parser->data;
        off_t i;
        //printf("%s %.*s HTTP/%d.%d\n", http_method_str(parser->method), (int) bbsr->headers[0].keylen, bbsr->headers[0].key, parser->http_major, parser->http_minor);
        /*
        for(i=1;i<=bbsr->header_pos;i++) {
                printf("%.*s: %.*s\n", (int) bbsr->headers[i].keylen, bbsr->headers[i].key, (int)bbsr->headers[i].vallen, bbsr->headers[i].value);
        }
        */

        // ok get the Host header
        struct bb_http_header *bbhh = bb_http_req_header(bbsr, "Host", 4);
        if (!bbhh) {
                return -1;
        }

        if (!bbsr->bbs->dealer) {
                bbsr->bbs->dealer = bb_get_dealer(bbsr->bbs->acceptor, bbhh->value, bbhh->vallen);
        	if (!bbsr->bbs->dealer) {
                	return -1;
        	}
        }

        if (parser->upgrade) {
                struct bb_http_header *bbhh = bb_http_req_header(bbsr, "Upgrade", 7);
                if (bbhh) {
                        if (!bb_stricmp("websocket", 9, bbhh->value, bbhh->vallen)) {
                                bbsr->type = BLASTBEAT_TYPE_WEBSOCKET;
                                bb_send_websocket_handshake(bbsr);
				goto msg;
                        }
                }
        }

        if (!http_should_keep_alive(parser)) {
                //printf("NO KEEP ALIVE !!!\n");
                bbsr->close = 1;
        }

msg:
        // now encode headers in a uwsgi packet and send it as "headers" message
	if (bb_uwsgi(bbsr)) {
		return -1;
	}
        bb_zmq_send_msg(bbsr->bbs->dealer->identity, bbsr->bbs->dealer->len, (char *) &bbsr->bbs->uuid_part1, BB_UUID_LEN, "uwsgi", 5, bbsr->uwsgi_buf, bbsr->uwsgi_pos);
        return 0;
}
Exemple #4
0
void bb_session_close(struct bb_session *bbs) {
	int i;
	ev_io_stop(blastbeat.loop, &bbs->reader.reader);
	ev_io_stop(blastbeat.loop, &bbs->writer.writer);
	if (bbs->ssl) {
		// this should be better managed, but why wasting resources ?
		// just ignore its return value
		SSL_shutdown(bbs->ssl);
		SSL_free(bbs->ssl);
	}
	close(bbs->fd);
	// remove the session from the hash table
	bb_sht_remove(bbs);
	struct bb_session_request *bbsr = bbs->requests_head;
	while(bbsr) {
		for(i=0;i<=bbsr->header_pos;i++) {
			free(bbsr->headers[i].key);
			free(bbsr->headers[i].value);
		}
		if (bbsr->uwsgi_buf) {
			free(bbsr->uwsgi_buf);
		}
		if (bbsr->websocket_message_queue) {
			free(bbsr->websocket_message_queue);
		}
		struct bb_session_request *tmp_bbsr = bbsr;
		bbsr = bbsr->next;
		free(tmp_bbsr);
	}

	struct bb_writer_item *bbwi = bbs->writer.head;
	while(bbwi) {
		struct bb_writer_item *old_bbwi = bbwi;	
		bbwi = bbwi->next;
		if (old_bbwi->free_it) {
			free(old_bbwi->buf);
		}
		free(old_bbwi);
	}

	// if linked to a dealer, send a 'end' message
	if (bbs->dealer) {
		bb_zmq_send_msg(bbs->dealer->identity, bbs->dealer->len, (char *) &bbs->uuid_part1, BB_UUID_LEN, "end", 3, "", 0);
	}

	free(bbs);
}
Exemple #5
0
static int body_cb(http_parser *parser, const char *buf, size_t len) {
        struct bb_session_request *bbsr = (struct bb_session_request *) parser->data;
        // send a message as "body"
	bb_zmq_send_msg(bbsr->bbs->dealer->identity, bbsr->bbs->dealer->len, (char *) &bbsr->bbs->uuid_part1, BB_UUID_LEN, "body", 4, buf, len);
        return 0;
}
Exemple #6
0
void bb_zmq_receiver(struct ev_loop *loop, struct ev_io *w, int revents) {

	uint32_t zmq_events = 0;
	size_t opt_len = sizeof(uint32_t);

	for(;;) {
		int ret = zmq_getsockopt(blastbeat.router, ZMQ_EVENTS, &zmq_events, &opt_len);		
		if (ret < 0) {
			perror("zmq_getsockopt()");
			break;
		}
	
		if (zmq_events & ZMQ_POLLIN) {
			uint64_t more = 0;
			size_t more_size = sizeof(more);
			int headers = 0;
			int i;
			zmq_msg_t msg[4];
			for(i=0;i<4;i++) {
				zmq_msg_init(&msg[i]);
				zmq_recv(blastbeat.router, &msg[i], ZMQ_NOBLOCK);
				if (zmq_getsockopt(blastbeat.router, ZMQ_RCVMORE, &more, &more_size)) {
					perror("zmq_getsockopt()");
					break;
				}
				if (!more && i < 3) {
					break;
				}
			}

			// invalid message
			if (i != 4) goto next;

			// manage "pong" messages

			// message with uuid ?
			if (zmq_msg_size(&msg[1]) != BB_UUID_LEN) goto next;

			// dead/invalid session ?
			struct bb_session *bbs = bb_sht_get(zmq_msg_data(&msg[1]));
			if (!bbs) goto next;

			struct bb_session_request *bbsr = bbs->requests_tail;
			// no request running ?
			if (!bbsr) goto next;

			if (!strncmp(zmq_msg_data(&msg[2]), "body", zmq_msg_size(&msg[2]))) {
				if (bb_wq_push_copy(bbs,zmq_msg_data(&msg[3]), zmq_msg_size(&msg[3]), 1)) {
					bb_session_close(bbs);
					goto next;
				}
				bbsr->written_bytes += zmq_msg_size(&msg[2]);
				// if Content-Length is specified, check it...
				if (bbsr->content_length != ULLONG_MAX && bbsr->written_bytes >= bbsr->content_length && bbsr->close) {
					if (bb_wq_push_close(bbs))
						bb_session_close(bbs);
				}
				goto next;
			}

			if (!strncmp(zmq_msg_data(&msg[2]), "websocket", zmq_msg_size(&msg[2]))) {
				if (bb_websocket_reply(bbsr, zmq_msg_data(&msg[3]), zmq_msg_size(&msg[3])))
					bb_session_close(bbs);
				goto next;
			}

			if (!strncmp(zmq_msg_data(&msg[2]), "chunk", zmq_msg_size(&msg[2]))) {
				if (bb_manage_chunk(bbsr, zmq_msg_data(&msg[3]), zmq_msg_size(&msg[3])))
					bb_session_close(bbs);
				goto next;
			}

			if (!strncmp(zmq_msg_data(&msg[2]), "headers", zmq_msg_size(&msg[2]))) {
				http_parser parser;
				http_parser_init(&parser, HTTP_RESPONSE);
				parser.data = bbsr;
				int res = http_parser_execute(&parser, &bb_http_response_parser_settings, zmq_msg_data(&msg[3]), zmq_msg_size(&msg[3]));
				// invalid headers ?
				if (res != zmq_msg_size(&msg[3])) {
					bb_session_close(bbs);	
					goto next;
				}
				if (bb_wq_push_copy(bbs, zmq_msg_data(&msg[3]), zmq_msg_size(&msg[3]), 1))
					bb_session_close(bbs);
				goto next;
			}

			if (!strncmp(zmq_msg_data(&msg[2]), "retry", zmq_msg_size(&msg[2]))) {
				if (bbs->hops >= blastbeat.max_hops) {
					bb_session_close(bbs);
					goto next;	
				}
				bbs->dealer = bb_get_dealer(bbs->acceptor, bbs->dealer->vhost->name, bbs->dealer->vhost->len);
                		if (!bbs->dealer) {
					bb_session_close(bbs);
					goto next;	
                		}
				bb_zmq_send_msg(bbs->dealer->identity, bbs->dealer->len, (char *) &bbs->uuid_part1, BB_UUID_LEN, "uwsgi", 5, bbsr->uwsgi_buf, bbsr->uwsgi_pos);
				bbs->hops++;
				goto next;
			}

			if (!strncmp(zmq_msg_data(&msg[2]), "end", zmq_msg_size(&msg[2]))) {
				if (bb_wq_push_close(bbs)) {
					bb_session_close(bbs);	
				}
				goto next;
			}

next:
			zmq_msg_close(&msg[0]);
			zmq_msg_close(&msg[1]);
			zmq_msg_close(&msg[2]);
			zmq_msg_close(&msg[3]);
		
			continue;
		}

		break;
	}
}