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; }
int bb_send_websocket_handshake(struct bb_session_request *bbsr) { char sha[20]; struct bb_http_header *swk = bb_http_req_header(bbsr, "sec-websocket-key", 17); if (!swk) return -1; struct bb_http_header *origin = bb_http_req_header(bbsr, "origin", 6); sha1(swk->value, swk->vallen, sha); size_t b_len = 20; char *b64 = base64(sha, &b_len); bbsr->http_major = '0' + bbsr->parser.http_major; bbsr->http_minor = '0' + bbsr->parser.http_minor; if (bb_wq_push(bbsr->bbs->connection, "HTTP/", 5, 0)) return -1; if (bb_wq_push(bbsr->bbs->connection, &bbsr->http_major, 1, 0)) return -1; if (bb_wq_push(bbsr->bbs->connection, ".", 1, 0)) return -1; if (bb_wq_push(bbsr->bbs->connection, &bbsr->http_minor, 1, 0)) return -1; if (bb_wq_push(bbsr->bbs->connection, " 101 WebSocket Protocol Handshake\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ", 98, 0)) return -1; if (bb_wq_push(bbsr->bbs->connection, b64, b_len, 1)) return -1; if (bb_wq_push(bbsr->bbs->connection, "\r\n\r\n", 4, 0)) return -1; return 0; }