/** * handles a client request */ static int write_request(stream_t *s, request_rec *r, config_t *config, cluster_t *cluster, int *keepalive, int session_index, int backup_index, char *ip, char *session_id) { int len; int code; int write_length; time_t new_time; time_t start_time = r->request_time; hmux_start_channel(s, 1); write_env(s, r, session_id); write_headers(s, r); write_added_headers(s, r); /* read post data */ if (ap_should_client_block(r)) { char buf[BUF_LENGTH]; int ack_size = s->cluster_srun->srun->send_buffer_size; int send_length = 0; while ((len = ap_get_client_block(r, buf, BUF_LENGTH)) > 0) { /* ap_reset_timeout(r); */ cse_write_packet(s, HMUX_DATA, buf, len); send_length += len; if (ack_size <= send_length) { send_length = 0; cse_write_byte(s, HMUX_YIELD); code = send_data(s, r, HMUX_ACK, keepalive); if (code < 0 || code == HMUX_QUIT || code == HMUX_EXIT) break; } } } cse_write_byte(s, HMUX_QUIT); code = send_data(s, r, HMUX_QUIT, keepalive); if (code >= 0 || s->sent_data) return code; write_length = s->write_length; if (cse_open_connection(s, cluster, session_index, backup_index, r->request_time, r->pool)) { s->write_length = write_length; LOG(("retry connection %d\n", s->socket)); return send_data(s, r, HMUX_QUIT, keepalive); } else { return HTTP_SERVICE_UNAVAILABLE; } }
/** * Writes SSL data, including client certificates. */ static void write_ssl(stream_t *s, EXTENSION_CONTROL_BLOCK *r) { char buf[BUF_LENGTH]; unsigned long size = sizeof(buf); if (! r->GetServerVariable(r->ConnID, "SERVER_PORT_SECURE", buf, &size) || size <= 0 || buf[0] != '1') return; cse_write_string(s, CSE_IS_SECURE, ""); // Anh : Add SSL connection informations cse_write_string(s, HMUX_HEADER, "HTTPS"); cse_write_string(s, HMUX_STRING, "on"); write_header(s, r, "HTTPS_KEYSIZE"); write_header(s, r, "HTTPS_SECRETKEYSIZE"); // Anh : Check client certificate existence size = sizeof(buf); buf[0] = 0; if (! r->GetServerVariable(r->ConnID, "CERT_FLAGS", buf, &size) || size <= 0 || buf[0] != '1') return; // There is a client certificate char cert_buf[BUF_LENGTH]={0}; CERT_CONTEXT_EX cert; cert.cbAllocated = sizeof(cert_buf); cert.CertContext.pbCertEncoded = (BYTE*) cert_buf; cert.CertContext.cbCertEncoded = 0; DWORD dwSize = sizeof(cert); if (r->ServerSupportFunction(r->ConnID, (DWORD)HSE_REQ_GET_CERT_INFO_EX, (LPVOID)&cert, &dwSize,NULL) != FALSE) { // cert now contains valid client certificate information LOG(("\ndwCertEncodingType = %d (%d) %ld\n", cert.CertContext.dwCertEncodingType & X509_ASN_ENCODING , cert.CertContext.cbCertEncoded, cert.dwCertificateFlags)); cse_write_packet(s, CSE_CLIENT_CERT, (char *)cert.CertContext.pbCertEncoded, cert.CertContext.cbCertEncoded); write_header(s, r, "CERT_ISSUER"); write_header(s, r, "CERT_SERIALNUMBER"); write_header(s, r, "CERT_SUBJECT"); write_header(s, r, "CERT_SERVER_ISSUER"); write_header(s, r, "CERT_SERVER_SUBJECT"); } }
/** * handles a client request */ static int write_request(stream_t *s, request_rec *r, config_t *config, int session_index, int backup_index) { int len; int code = -1; write_env(s, r); write_headers(s, r); write_added_headers(s, r); /* read post data */ if (ap_should_client_block(r)) { char buf[BUF_LENGTH]; int ack_size = s->cluster_srun->srun->send_buffer_size; int send_length = 0; while ((len = ap_get_client_block(r, buf, BUF_LENGTH)) > 0) { LOG(("%s:%d:write-request(): w-D %d\n", __FILE__, __LINE__, len)); if (ack_size <= send_length + len && send_length > 0) { LOG(("%s:%d:write-request(): w-Y send_length=%d ack_size=%d\n", __FILE__, __LINE__, send_length, ack_size)); send_length = 0; cse_write_byte(s, HMUX_YIELD); code = send_data(s, r); if (code != HMUX_ACK) break; } cse_write_packet(s, HMUX_DATA, buf, len); send_length += len; } } LOG(("%s:%d:write-request(): w-Q\n", __FILE__, __LINE__)); cse_write_byte(s, HMUX_QUIT); code = send_data(s, r); LOG(("%s:%d:write_request(): return code %c\n", __FILE__, __LINE__, code)); return code; }