⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.cpp

📁 RESIN 3.2 最新源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1999-2008 Caucho Technology.  All rights reserved. * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson *//* * SSL client certificate contributed by Ahn Le *//* * Anh: We have to define _WIN32_WINNT as 0x0400 to have access to * the Crypto API.  By definning as this way, the dll can only work * with Windows 95 OEM Service Release 2 or above. */ #define _WIN32_WINNT 0x0400#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <windows.h>#include "httpext.h"#include <errno.h>#include <ctype.h>#include <string.h>#define ISAPI_SCRIPT "/scripts/isapi_srun.dll"extern "C" {#include "../common/cse.h"#include "../common/version.h"}extern "C" {voidcse_error(config_t *config, char *fmt, ...){	va_list arg;	char buf[1024];	va_start(arg, fmt);	if (fmt)		vsprintf(buf, fmt, arg);	else		buf[0] = 0;	va_end(arg);	if (buf[0]) {		config->error = strdup(buf);                config->enable_caucho_status = 1;        }#ifdef DEBUG	{		FILE *file;	    file = fopen("/temp/isapi.log", "a+b");		fprintf(file, "%s\n", buf);		fclose(file);	}#endif}void *cse_malloc(int size){  return malloc(size);}void cse_free(config_t *config, void *value) {}voidcse_set_socket_cleanup(int socket, void *pool){}voidcse_kill_socket_cleanup(int socket, void *pool){}}voidcse_log(char *fmt, ...){#ifdef DEBUG	va_list arg;	FILE *file;	file = fopen("/temp/isapi.log", "a+");	va_start(arg, fmt);	if (file)		vfprintf(file, fmt, arg);	va_end(arg);	fclose(file);#endif}void *cse_create_lock(config_t *config){	return CreateMutex(0, false, 0);}voidcse_free_lock(config_t *config, void *lock){}intcse_lock(void *lock){	if (lock) {		WaitForSingleObject(lock, INFINITE);	}	return 1;}voidcse_unlock(void *lock){	if (lock) {		ReleaseMutex(lock);	}}static voidcse_printf(EXTENSION_CONTROL_BLOCK *r, char *fmt, ...){  va_list args;  char buf[4096];  unsigned long len;  va_start(args, fmt);  vsprintf(buf, fmt, args);  va_end(args);  len = strlen(buf);  r->WriteClient(r->ConnID, buf, &len, 0);}static voidcse_pad(EXTENSION_CONTROL_BLOCK *r){  cse_printf(r, "\n\n\n\n");  cse_printf(r, "<!--\n");  cse_printf(r, "   - Unfortunately, Microsoft has added a clever new\n");  cse_printf(r, "   - \"feature\" to Internet Explorer.  If the text in\n");  cse_printf(r, "   - an error's message is \"too small\", specifically\n");  cse_printf(r, "   - less than 512 bytes, Internet Explorer returns\n");  cse_printf(r, "   - its own error message.  Yes, you can turn that\n");  cse_printf(r, "   - off, but *surprise* it's pretty tricky to find\n");  cse_printf(r, "   - buried as a switch called \"smart error\n");  cse_printf(r, "   - messages\"  That means, of course, that many of\n");  cse_printf(r, "   - Resin's error messages are censored by default.\n");  cse_printf(r, "   - And, of course, you'll be shocked to learn that\n");  cse_printf(r, "   - IIS always returns error messages that are long\n");  cse_printf(r, "   - enough to make Internet Explorer happy.  The\n");  cse_printf(r, "   - workaround is pretty simple: pad the error\n");  cse_printf(r, "   - message with a big comment to push it over the\n");  cse_printf(r, "   - five hundred and twelve byte minimum.  Of course,\n");  cse_printf(r, "   - that's exactly what you're reading right now.\n");  cse_printf(r, "   -->\n");}static intconnection_error(config_t *config, EXTENSION_CONTROL_BLOCK *r){  // r->content_type = "text/html";  // ap_send_http_header(r);  char *hostname = 0;  int port = 0;  if (config->error_page && config->error_page[0]) {	  DWORD size = strlen(config->error_page);	  DWORD type = 0;          cse_printf(r, "HTTP/1.0 302 Redirect\r\n");          cse_printf(r, "Location: %s\r\n", config->error_page);          cse_printf(r, "\r\n");          	  return 1;  }  cse_printf(r, "HTTP/1.0 503 Busy\n\n");  cse_printf(r, "<html><body bgcolor='white'>\n");  cse_printf(r, "<h1>Server is currently unavailable or down for maintenance\n");  cse_printf(r, "</h1>\n");  cse_printf(r, "</body></html>\n");    cse_pad(r);   return 1;}static intcse_error(config_t *config, EXTENSION_CONTROL_BLOCK *r){  // r->content_type = "text/html";  // ap_send_http_header(r);  if (config->error_page) {	  DWORD size = strlen(config->error_page);	  DWORD type = 0;		cse_printf(r, "HTTP/1.0 302 Redirect\n");		cse_printf(r, "Location: %s\n", config->error_page);		cse_printf(r, "\n");		return 1;  }  cse_printf(r, "HTTP/1.0 500 Server Error\n\n");  cse_printf(r, "<html><body bgcolor='white'>\n");  cse_printf(r, "<h1>Can't access URL</h1>\n");  if (config->error)	  cse_printf(r, "<pre>%s</pre>", config->error);  cse_printf(r, "</body></html>\n");    cse_pad(r);   return 1;}static voidwrite_var(stream_t *s, EXTENSION_CONTROL_BLOCK *r, char *name, int code){	char buf[BUF_LENGTH];        char *ptr;	unsigned long size = sizeof(buf);	buf[0] = 0;	if (r->GetServerVariable(r->ConnID, name, buf, &size) && size > 0 && buf[0]) {		buf[size] = 0;                                for (ptr = buf; isspace(*ptr); ptr++) {                }                		cse_write_string(s, code, ptr);	}}static voidwrite_header(stream_t *s, EXTENSION_CONTROL_BLOCK *r, char *name){  char buf[BUF_LENGTH];  unsigned long size = sizeof(buf);  char *ptr = buf;  buf[0] = 0;	if (r->GetServerVariable(r->ConnID, name, buf, &size) && size > 0 && buf[0]) {                for (; size > 0 && isspace(buf[size - 1]); size--) {                }		buf[size] = 0;		cse_write_string(s, HMUX_HEADER, name);                for (ptr = buf; isspace(*ptr); ptr++) {                }                		cse_write_string(s, HMUX_STRING, ptr); 	}}/** * Writes SSL data, including client certificates. */static voidwrite_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");	}}static inthexify(char *uri, int offset, int ch){  int d1 = (ch >> 4) & 0xf;  int d2 = ch & 0xf;  uri[offset++] = '%';  uri[offset++] = (d1 < 10) ? (d1 + '0') : (d1 - 10 + 'A');  uri[offset++] = (d2 < 10) ? (d2 + '0') : (d2 - 10 + 'A');  return offset;}static int write_env(stream_t *s, EXTENSION_CONTROL_BLOCK *r){	int isHttp11 = 0;	char protocol[BUF_LENGTH];	char path_info_buffer[BUF_LENGTH];	char *path_info = path_info_buffer;	char uri_buffer[BUF_LENGTH];	char *uri = uri_buffer;	unsigned long size = sizeof(protocol);	if (r->GetServerVariable(r->ConnID, "SERVER_PROTOCOL", protocol, &size) && size > 0) {		protocol[size] = 0;		isHttp11 = ! strcmp(protocol, "HTTP/1.1");	}	size = sizeof(path_info_buffer);	if (r->GetServerVariable(r->ConnID, "PATH_INFO", path_info, &size) && size > 0) {	        int i;	  		path_info[size] = 0;		if (! strncmp(path_info, ISAPI_SCRIPT, sizeof(ISAPI_SCRIPT) - 1))			path_info += sizeof(ISAPI_SCRIPT) - 1;		i = 0;		while (i < BUF_LENGTH - 6) {		  int ch = *path_info++ & 0xff;		  if (ch == 0)		    break;		  else if (' ' <= ch && ch < 0x80 && ch != '%') {		    uri[i++] = ch;		  }		  else if (ch < 0x80) {		    i = hexify(uri, i, ch);		  }		  else {		    i = hexify(uri, i, 0xc0 | ((ch >> 6) & 0x1f));		    i = hexify(uri, i, 0x80 | (ch & 0x3f));		  }		}		uri[i] = 0;	}	else		uri[size] = 0;	hmux_start_channel(s, 1);	cse_write_string(s, HMUX_URL, uri);	write_var(s, r, "REQUEST_METHOD", HMUX_METHOD);	write_var(s, r, "SERVER_PROTOCOL", CSE_PROTOCOL);	//	write_var(s, r, "PATH_TRANSLATED", CSE_PATH_TRANSLATED);	write_var(s, r, "QUERY_STRING", CSE_QUERY_STRING);	write_var(s, r, "SERVER_NAME", HMUX_SERVER_NAME);	write_var(s, r, "SERVER_PORT", CSE_SERVER_PORT);	write_var(s, r, "REMOTE_HOST", CSE_REMOTE_HOST);	write_var(s, r, "REMOTE_ADDR", CSE_REMOTE_ADDR);	write_var(s, r, "REMOTE_USER", CSE_REMOTE_USER);	write_var(s, r, "AUTH_TYPE", CSE_AUTH_TYPE);	// write_var(s, r, "CONTENT_TYPE", CSE_CONTENT_TYPE);	// write_var(s, r, "CONTENT_LENGTH", CSE_CONTENT_LENGTH);  // cse_write_string(s, CSE_DOCROOT, ap_document_root(r));  //	sprintf(buf, "%d", s->srun->session);	cse_write_string(s, CSE_SERVER_TYPE, "ISAPI");	write_ssl(s, r);	return isHttp11;}static voidwrite_headers(stream_t *s, EXTENSION_CONTROL_BLOCK *r){	char buf[16384];	unsigned long i = 0;	unsigned long len = sizeof(buf);	if (! r->GetServerVariable(r->ConnID, "ALL_RAW", buf, &len))		return;	while (i < len) {	  int ch;	  int j;	  		for (; i < len && isspace(buf[i]); i++) {		}		int head = i;		int tail;		for (; i < len && (ch = buf[i]) != ':'; i++) {		  if (isspace(ch))		    buf[i] = 0;		}		buf[i] = 0;		for (i++;		     (i < len && ((ch = buf[i]) == ' ' || ch == '\t') && ch != '\n');		      i++) {		}		tail = i;		for (; i < len && (buf[i] != '\n' || isspace(buf[i+1])); i++) {			if (isspace(buf[i]))				buf[i] = ' ';		}		for (j = i - 1; tail <= j && isspace(buf[j]); j--) {		  buf[j] = 0;		}		buf[i++] = 0;		if (buf[head]) {			cse_write_string(s, HMUX_HEADER, buf + head);			cse_write_string(s, HMUX_STRING, buf + tail);		}	}}static intwrite_client_buffer(EXTENSION_CONTROL_BLOCK *r, void *v_buf, int len){	char *buffer = (char *) v_buf;	while (len > 0) {		unsigned long sentlen = len;		if (! r->WriteClient(r->ConnID, buffer, &sentlen, HSE_IO_SYNC) || 			sentlen <= 0) {			return -1;		}		len -= sentlen;		buffer += sentlen;	}	return 0;}static intcse_write_response(stream_t *s, unsigned long len, EXTENSION_CONTROL_BLOCK *r){	while (len > 0) {		unsigned long sublen;		if (s->read_offset >= s->read_length) {		  if (cse_fill_buffer(s) < 0) {		    connection_error(s->config, r);		    return -1;		  }		}		sublen = s->read_length - s->read_offset;		if (len < sublen)			sublen = len;		s->read_buf[s->read_length] = 0;		if (write_client_buffer(r, s->read_buf + s->read_offset,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -