static int websocket_handshake(swListenPort *port, http_context *ctx) { #if PHP_MAJOR_VERSION < 7 TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); #endif zval *header = ctx->request.zheader; HashTable *ht = Z_ARRVAL_P(header); zval *pData; if (sw_zend_hash_find(ht, ZEND_STRS("sec-websocket-key"), (void **) &pData) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "header no sec-websocket-key"); return SW_ERR; } convert_to_string(pData); swString_clear(swoole_http_buffer); swString_append_ptr(swoole_http_buffer, ZEND_STRL("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n")); int n; char sec_websocket_accept[128]; memcpy(sec_websocket_accept, Z_STRVAL_P(pData), Z_STRLEN_P(pData)); memcpy(sec_websocket_accept + Z_STRLEN_P(pData), SW_WEBSOCKET_GUID, sizeof(SW_WEBSOCKET_GUID) - 1); char sha1_str[20]; bzero(sha1_str, sizeof(sha1_str)); php_swoole_sha1(sec_websocket_accept, Z_STRLEN_P(pData) + sizeof(SW_WEBSOCKET_GUID) - 1, (unsigned char *) sha1_str); char encoded_str[50]; bzero(encoded_str, sizeof(encoded_str)); n = swBase64_encode((unsigned char *) sha1_str, sizeof(sha1_str), encoded_str); char _buf[128]; n = snprintf(_buf, sizeof(_buf), "Sec-WebSocket-Accept: %*s\r\n", n, encoded_str); swString_append_ptr(swoole_http_buffer, _buf, n); swString_append_ptr(swoole_http_buffer, ZEND_STRL("Sec-WebSocket-Version: "SW_WEBSOCKET_VERSION"\r\n")); if (port->websocket_subprotocol) { swString_append_ptr(swoole_http_buffer, ZEND_STRL("Sec-WebSocket-Protocol: ")); swString_append_ptr(swoole_http_buffer, port->websocket_subprotocol, port->websocket_subprotocol_length); swString_append_ptr(swoole_http_buffer, ZEND_STRL("\r\n")); } swString_append_ptr(swoole_http_buffer, ZEND_STRL("Server: "SW_WEBSOCKET_SERVER_SOFTWARE"\r\n\r\n")); swTrace("websocket header len:%ld\n%s \n", swoole_http_buffer->length, swoole_http_buffer->str); return swServer_tcp_send(SwooleG.serv, ctx->fd, swoole_http_buffer->str, swoole_http_buffer->length); }
static int mysql_handshake(mysql_connector *connector, char *buf, int len) { char *tmp = buf; /** * handshake request */ mysql_handshake_request request; bzero(&request, sizeof(request)); request.packet_length = mysql_uint3korr(tmp); //continue to wait for data if (len < request.packet_length + 4) { return 0; } request.packet_number = tmp[3]; tmp += 4; request.protocol_version = *tmp; tmp += 1; //ERROR Packet if (request.protocol_version == 0xff) { connector->error_code = *(uint16_t *) tmp; connector->error_msg = tmp + 2; connector->error_length = request.packet_length - 3; return -1; } request.server_version = tmp; tmp += (strlen(request.server_version) + 1); request.connection_id = *((int *) tmp); tmp += 4; memcpy(request.auth_plugin_data, tmp, 8); tmp += 8; request.filler = *tmp; tmp += 1; memcpy(((char *) (&request.capability_flags)) + 2, tmp, 2); tmp += 2; if (tmp - tmp < len) { request.character_set = *tmp; tmp += 1; memcpy(&request.status_flags, tmp, 2); tmp += 2; memcpy(&request.capability_flags, tmp, 2); tmp += 2; request.l_auth_plugin_data = *tmp; tmp += 1; memcpy(&request.reserved, tmp, sizeof(request.reserved)); tmp += sizeof(request.reserved); if (request.capability_flags & SW_MYSQL_CLIENT_SECURE_CONNECTION) { int len = MAX(13, request.l_auth_plugin_data - 8); memcpy(request.auth_plugin_data + 8, tmp, len); tmp += len; } if (request.capability_flags & SW_MYSQL_CLIENT_PLUGIN_AUTH) { request.auth_plugin_name = tmp; request.l_auth_plugin_name = strlen(tmp); } } int value; tmp = connector->buf + 4; //capability flags, CLIENT_PROTOCOL_41 always set value = SW_MYSQL_CLIENT_PROTOCOL_41 | SW_MYSQL_CLIENT_SECURE_CONNECTION | SW_MYSQL_CLIENT_CONNECT_WITH_DB | SW_MYSQL_CLIENT_PLUGIN_AUTH; memcpy(tmp, &value, sizeof(value)); tmp += 4; //max-packet size value = 300; memcpy(tmp, &value, sizeof(value)); tmp += 4; //character set *tmp = connector->character_set; tmp += 1; //string[23] reserved (all [0]) tmp += 23; //string[NUL] username memcpy(tmp, connector->user, connector->user_len); tmp[connector->user_len] = '\0'; tmp += (connector->user_len + 1); //auth-response char hash_0[20]; bzero(hash_0, sizeof(hash_0)); php_swoole_sha1(connector->password, connector->password_len, (uchar *) hash_0); char hash_1[20]; bzero(hash_1, sizeof(hash_1)); php_swoole_sha1(hash_0, sizeof(hash_0), (uchar *) hash_1); char str[40]; memcpy(str, request.auth_plugin_data, 20); memcpy(str + 20, hash_1, 20); char hash_2[20]; php_swoole_sha1(str, sizeof(str), (uchar *) hash_2); char hash_3[20]; int *a = (int *) hash_2; int *b = (int *) hash_0; int *c = (int *) hash_3; int i; for (i = 0; i < 5; i++) { c[i] = a[i] ^ b[i]; } *tmp = 20; memcpy(tmp + 1, hash_3, 20); tmp += 21; //string[NUL] database memcpy(tmp, connector->database, connector->database_len); tmp[connector->database_len] = '\0'; tmp += (connector->database_len + 1); //string[NUL] auth plugin name memcpy(tmp, request.auth_plugin_name, request.l_auth_plugin_name); tmp[request.l_auth_plugin_name] = '\0'; tmp += (request.l_auth_plugin_name + 1); connector->packet_length = tmp - connector->buf - 4; mysql_pack_length(connector->packet_length, connector->buf); connector->buf[3] = 1; return 1; }