/**
 * 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;
  }
}
示例#2
0
/**
 * 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;
}