VB6之HTTP服务器的实现(二)

接上篇,这次做了小小的改动和提升。增加了对POST的支持和对其他方法(GET和POST之外的)选择405回复。另外,增加了对CGI的支持,目前可以使用C语言来写(是不是好蠢的赶脚)。相对于上篇,整体做了小小的优化。这次代码就只贴mod_cgi.bas的部分,其他文件我打包了,感兴趣的同学可以下来看看。

注:由于我不是很了解WebServer,写这个东西也是盲人摸象。像什么状态控制、任务调度、容错之类的基本上能省则省,另外也是因为不会写,哈哈。如果有不足之处,还请不吝赐教,右路西裤(霓虹语:请多多指教)!

  1 ‘mod_cgi.bas
  2 ‘code by lichmama from cnblogs.com
  3 ‘CGI支持状态
  4 Public CGI_ENABLED As Boolean
  5 ‘CGI程序目录
  6 Public Const CGI_ROOT As String = "c:\cgi-bin\"
  7
  8 Private Declare Function CreatePipe Lib "kernel32" ( _
  9         phReadPipe As Long, _
 10         phWritePipe As Long, _
 11         lpPipeAttributes As SECURITY_ATTRIBUTES, _
 12         ByVal nSize As Long) As Long
 13
 14 Private Declare Sub GetStartupInfo Lib "kernel32" Alias "GetStartupInfoA" ( _
 15         lpStartupInfo As STARTUPINFO)
 16
 17 Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" ( _
 18         ByVal lpApplicationName As String, _
 19         ByVal lpCommandLine As String, _
 20         lpProcessAttributes As Any, _
 21         lpThreadAttributes As Any, _
 22         ByVal bInheritHandles As Boolean, _
 23         ByVal dwCreationFlags As Long, _
 24         lpEnvironment As Any, _
 25         ByVal lpCurrentDriectory As String, _
 26         lpStartupInfo As STARTUPINFO, _
 27         lpProcessInformation As PROCESS_INFORMATION) As Long
 28
 29 Private Declare Function ReadFile Lib "kernel32" ( _
 30         ByVal hFile As Long, _
 31         lpBuffer As Any, _
 32         ByVal nNumberOfBytesToRead As Long, _
 33         lpNumberOfBytesRead As Long, _
 34         lpOverlapped As Any) As Long
 35
 36 Private Declare Function CloseHandle Lib "kernel32" ( _
 37         ByVal hObject As Long) As Long
 38
 39 Private Type SECURITY_ATTRIBUTES
 40     nLength As Long
 41     lpSecurityDescriptor As Long
 42     bInheritHandle As Long
 43 End Type
 44
 45 Private Type PROCESS_INFORMATION
 46     hProcess As Long
 47     hThread As Long
 48     dwProcessId As Long
 49     dwThreadId As Long
 50 End Type
 51
 52 Private Type STARTUPINFO
 53     cb As Long
 54     lpReserved As Long
 55     lpDesktop As Long
 56     lpTitle As Long
 57     dwX As Long
 58     dwY As Long
 59     dwXSize As Long
 60     dwYSize As Long
 61     dwXCountChars As Long
 62     dwYCountChars As Long
 63     dwFillAttribute As Long
 64     dwFlags As Long
 65     wShowWindow As Integer
 66     cbReserved2 As Integer
 67     lpReserved2 As Byte
 68     hStdInput As Long
 69     hStdOutput As Long
 70     hStdError As Long
 71 End Type
 72
 73 Private Type OVERLAPPED
 74     ternal As Long
 75     ternalHigh As Long
 76     offset As Long
 77     OffsetHigh As Long
 78     hEvent As Long
 79 End Type
 80
 81 Private Const STARTF_USESHOWWINDOW = &H1
 82 Private Const STARTF_USESTDHANDLES = &H100
 83 Private Const SW_HIDE = 0
 84 Private Declare Sub RtlZeroMemory Lib "kernel32" (dest As Any, ByVal _
 85     numBytes As Long)
 86
 87
 88 Public Function ShellCGI(ByVal head As Object, rep_state As Long) As String
 89     Dim sa As SECURITY_ATTRIBUTES
 90     Dim si As STARTUPINFO
 91     Dim pi As PROCESS_INFORMATION
 92     Dim hrp As Long
 93     Dim hwp As Long
 94     Dim ret As Long
 95     Dim envstr As String
 96
 97     ‘fill this with CGI standard envrionment strings,
 98     ‘   which delimited by chr(0)
 99     envstr = MakeEnvString(head)
100     Call RtlZeroMemory(ByVal VarPtr(sa), Len(sa))
101     Call RtlZeroMemory(ByVal VarPtr(si), Len(si))
102     Call RtlZeroMemory(ByVal VarPtr(pi), Len(pi))
103
104     sa.nLength = Len(sa)
105     sa.lpSecurityDescriptor = 0&
106     sa.bInheritHandle = 1&
107
108     ‘create pipe
109     ret = CreatePipe(hrp, hwp, sa, 0&)
110     If ret = 0 Then
111         Debug.Print "[HTTP-VBS]: CGI Exception, pipe failed"
112         Exit Function
113     End If
114
115     si.cb = Len(si)
116     si.hStdOutput = hwp
117     si.hStdError = hwp
118     si.dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
119     si.wShowWindow = SW_HIDE
120
121     ‘create the cgi-process, cgi-path: head("Path_Translated")
122     ret = CreateProcess(head("Path_Translated"), vbNullString, _
123         ByVal 0&, ByVal 0&, True, 0&, ByVal envstr, vbNullString, si, pi)
124     If ret = 0 Then
125         Debug.Print "[HTTP-VBS]: CGI Exception, create process failed"
126         Exit Function
127     End If
128
129     ‘read response from cgi
130     Dim nobr As Long ‘num of bytes read
131     Dim lpbuff As String
132     Dim szbuff(65536 * 100) As Byte
133     Dim sum As Long
134     sum = 0
135     Call RtlZeroMemory(ByVal VarPtr(szbuff(0)), 65536 * 100)
136     Do
137         nobr = 0&
138         lpbuff = String(1024, " ")
139         If ReadFile(hrp, ByVal lpbuff, 1024&, nobr, ByVal 0&) Then
140             Call RtlMoveMemory(ByVal VarPtr(szbuff(sum)), ByVal StrPtr(lpbuff), LenB(lpbuff))
141             sum = sum + LenB(lpbuff)
142         Else
143             Exit Do
144         End If
145         Call CloseHandle(hwp)
146     Loop
147     Call CloseHandle(hrp)
148
149     rep_state = 200
150     ShellCGI = Left(szbuff, sum)
151 End Function
152
153 Private Function MakeEnvString(ByVal head As Object) As String
154     MakeEnvString = "REQUEST_METHOD=" & head("Request")("Method") & Chr(0) & _
155         "CONTENT_TYPE=" & head("Content-Type") & Chr(0) & _
156         "CONTENT_LENGTH=" & head("Content-Length") & Chr(0) & _
157         "QUERY_STRING=" & head("Query_String") & Chr(0) & _
158         "SCRIPT_NAME=" & head("Script_Name") & Chr(0) & _
159         "PATH_INFO=" & head("Path_Info") & Chr(0) & _
160         "PATH_TRANSLATED=" & head("Path_Translated") & Chr(0) & _
161         "REMOTE_HOST=" & head("Remote_Host") & Chr(0) & _
162         "REMOTE_ADDR=" & head("Remote_Addr") & Chr(0) & _
163         "REMOTE_PORT=" & head("Remote_Port") & Chr(0) & _
164         "REMOTE_USER=" & head("Remote_User") & Chr(0) & _
165         "REMOTE_IDENT=" & head("Remote_Ident") & Chr(0) & _
166         "AUTH_TYPE=" & head("Auth_Type") & Chr(0) & _
167         "SERVER_NAME=http-vb/0.1" & Chr(0) & _
168         "SERVER_PORT=80" & Chr(0) & _
169         "SERVER_PROTOCOL=HTTP/1.1" & Chr(0) & _
170         "DOCUMENT_ROOT=" & head("Document_Root") & Chr(0) & _
171         "SERVER_SOFTWARE=http-vb/0.1 vb/6.0" & Chr(0) & _
172         "HTTP_ACCEPT=" & head("Accept") & Chr(0) & _
173         "HTTP_USER_AGENT=" & head("User-Agent") & Chr(0) & _
174         "HTTP_REFERER=" & head("Referer") & Chr(0) & _
175         "HTTP_COOKIE=" & head("Cookie") & Chr(0) & _
176         "GATEWAY_INTERFACE=CGI/1.1" & Chr(0)
177 End Function

CGI的代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <windows.h>
 4 #define ENV_MAX_LENGTH 0x7fff
 5
 6 char *GetEnv(const char *lpName, char *lpbuff){
 7     memset(lpbuff, 0, ENV_MAX_LENGTH);
 8     GetEnvironmentVariable(lpName, lpbuff, ENV_MAX_LENGTH);
 9     return lpbuff;
10 }
11
12 int main(int argc, char *argv[]){
13     char lpbuff[ENV_MAX_LENGTH]={0};
14     printf("Content-Type: text/html; charset=utf-8\n");
15     printf("\n");
16     printf("<html>\n");
17     printf("<head>\n");
18     printf("<meta content=‘text/html; charset=utf-8‘ http-equiv=‘content-type‘ />\n");
19     printf("<title>cgi [email protected]</title>\n");
20     printf("</head>\n");
21     printf("<body>\n");
22     printf("<ul style=‘font-family:courier new‘>\n");
23     printf("<li>REQUEST_METHOD: %s</li>\n", GetEnv("REQUEST_METHOD", lpbuff));
24     printf("<li>CONTENT_TYPE: %s</li>\n",   GetEnv("CONTENT_TYPE", lpbuff));
25     printf("<li>CONTENT_LENGTH: %s</li>\n", GetEnv("CONTENT_LENGTH", lpbuff));
26     printf("<li>QUERY_STRING: %s</li>\n",   GetEnv("QUERY_STRING", lpbuff));
27     printf("<li>SCRIPT_NAME: %s</li>\n",    GetEnv("SCRIPT_NAME", lpbuff));
28     printf("<li>PATH_INFO: %s</li>\n",      GetEnv("PATH_INFO", lpbuff));
29     printf("<li>PATH_TRANSLATED: %s</li>\n",GetEnv("PATH_TRANSLATED", lpbuff));
30     printf("<li>REMOTE_HOST: %s</li>\n",    GetEnv("REMOTE_HOST", lpbuff));
31     printf("<li>REMOTE_ADDR: %s</li>\n",    GetEnv("REMOTE_ADDR", lpbuff));
32     printf("<li>REMOTE_PORT: %s</li>\n",    GetEnv("REMOTE_PORT", lpbuff));
33     printf("<li>REMOTE_USER: %s</li>\n",    GetEnv("REMOTE_USER", lpbuff));
34     printf("<li>REMOTE_IDENT: %s</li>\n",   GetEnv("REMOTE_IDENT", lpbuff));
35     printf("<li>AUTH_TYPE: %s</li>\n",      GetEnv("AUTH_TYPE", lpbuff));
36     printf("<li>GATEWAY_INTERFACE: %s</li>\n", GetEnv("GATEWAY_INTERFACE", lpbuff));
37     printf("<li>SERVER_NAME: %s</li>\n",    GetEnv("SERVER_NAME", lpbuff));
38     printf("<li>SERVER_PORT: %s</li>\n",    GetEnv("SERVER_PORT", lpbuff));
39     printf("<li>SERVER_PROTOCOL: %s</li>\n",GetEnv("SERVER_PROTOCOL", lpbuff));
40     printf("<li>DOCUMENT_ROOT: %s</li>\n",  GetEnv("DOCUMENT_ROOT", lpbuff));
41     printf("<li>SERVER_SOFTWARE: %s</li>\n",GetEnv("SERVER_SOFTWARE", lpbuff));
42     printf("<li>HTTP_ACCEPT: %s</li>\n",    GetEnv("HTTP_ACCEPT", lpbuff));
43     printf("<li>HTTP_USER_AGENT: %s</li>\n",GetEnv("HTTP_USER_AGENT", lpbuff));
44     printf("<li>HTTP_REFERER: %s</li>\n",   GetEnv("HTTP_REFERER", lpbuff));
45     printf("<li>HTTP_COOKIE: %s</li>\n",    GetEnv("HTTP_COOKIE", lpbuff));
46     printf("</ul>\n");
47     printf("</body>\n");
48     printf("</html>\n");
49     return 0;
50 }

贴张图,看看效果(看到.exe会不会觉得邪恶):

咦,怎么添加附件?先来个百度云盘吧。

VB6之HTTP服务器的实现(二)

时间: 2024-11-09 11:39:08

VB6之HTTP服务器的实现(二)的相关文章

基于JDK7 NIO2的高性能web服务器实践之二(转)

前一篇博客,我简单提了下怎么为NIO2增加TransmitFile支持,文件传送吞吐量是一个性能关注点,此外,并发连接数也是重要的关注点. 不过JDK7中又一次做了简单的实现,不支持同时投递多个AcceptEx请求,只支持一次一个,返回后再投递.这样,客户端连接的接受速度必然大打折扣.不知道为什么sun会做这样的实现,WSASend()/WSAReceive()一次只允许一个还是可以理解,毕竟简化了编程,不用考虑封包乱序问题.也降低了内存耗尽的风险.AcceptEx却没有这样的理由了. 于是再一

[Java聊天室服务器]实战之二 监听类

前言 学习任何一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列虽然涉及的是socket相关的知识,但学习之前,更想和广大程序员分享的是一种心境:学习是一个循序渐进的过程,心态应该随时调节,保持戒骄戒躁的状态.比如最近在看网易公开课MIT<算法导论>,老师提到,学习算法之前要计算机数学+离散数学+概率论等课程的知识,所以一直学不好算法的程序员不妨从基础入手,这都是中国式教育惹的祸啊!(此处省略一万字......)

高效缓存服务器Memcached(二)

一.Memcache 应用一 php与memcache 1.PHP的memcache的客户端 PHP有两个memcache客户端:php memcache和php memcached.php memcache独立用php实现,是老客户端,从我们实践中已发现有多个问题,而且功能少,属性也可设置的少:php memcached是基于原生的c的libmemcached的扩展,更加完善,建议替换为php memcached. 2.PHP memcache的问题 (1).分布式问题 php memcach

高性能web服务器nginx(二)之常用功能举例

一.配置使用nginx 1.提供测试页 [[email protected] ~]# mkdir /www/a.com/htdoc [[email protected] ~]# cat /www/a.com/htdoc/index.html  <h1>www.a.com</h1> [[email protected] ~]# chown -R nginx.nginx /www/a.com/htdoc/ 2.备份配置文件并简要更改配置文件 [[email protected] ~]#

tomcat服务器介绍之二 、session服务器实现方法

上次讲到了session会话的绑定,通过nginx和apache(3种方式)实现 session会话的复制,通过DeltaManager和apache(mod_jk)实现 这次讲解基于msm实现session服务器的过程,需要用到的软件包如下: 一.准备工作,先部署nginx可以反向代理客户端请求至2台tomcat服务器 测试环境在centos7上,使用nginx和tomcat7实现:参考网页 https://code.google.com/p/memcached-session-manager

高性能服务器架构(二):缓存清理策略

原文链接:https://mp.weixin.qq.com/s/OopSWbLrzT-V11VDZOpxJw 虽然使用缓存思想似乎是一个很简单的事情,但是缓存机制却有一个核心的难点,就是--缓存清理.我们所说的缓存,都是保存一些数据,但是这些数据往往是会变化的,我们要针对这些变化,清理掉保存的"脏"数据,却可能不是那么容易. 首先我们来看看最简单的缓存数据--静态数据.这种数据往往在程序的运行时是不会变化的,比如Web服务器内存中缓存的HTML文件数据,就是这种.事实上,所有的不是由外

Linux基础篇之FTP服务器搭建(二)

上一篇文章说到了搭建FTP匿名用户的访问,接下来讲解一下本地用户的登录. 一.首先先建立一个用户,这里举例:xiaoming,并为其设置密码. 二.修改配置文件. 文件:ftpusers 文件:user_list 文件:vsftpd.conf 三.重新启动服务. 四.测试. 新建目录测试: 这样,本地用户就可以登录FTP服务器. 原文地址:https://www.cnblogs.com/641055499-mozai/p/11577301.html

socket本地模拟服务器+客户端(二)

建立两个py文件,分别打开两个cmd界面,即可进行通信.服务器端运用多进程,连续不断的处理从客户端接收到的数据:客户端通过一个list不断给客户端发送数据. (每个连接都必须创建新线程(或进程)来处理,否则,单线程在处理连接的过程中,无法接受其他客户端的连接.)本例中,多进程其实没有起到作用. 代码以及解释如下: #socket服务器端程序 import socket import time from multiprocessing import Process #多进程和多线程一样的用法 de

Mangos服务器框架设计分析(二)

在上一篇博文中,我们分析了Mangos服务器的登陆服务器,Mangos登陆服务器主要就是验证用户的合法性,并且针对通过验证的用户发送游戏列表服务器列表,用户选择了相关游戏服务器时所涉及到的流程就是今天本博文需要分析的,Mangos游戏服务器的主要架构就是一对多的关系,下层的I/O是多线程的,而上层的游戏主逻辑是单线程的,两者的胶合部分就是已经封装好的session模块,好了,下面就来看看具体的流程细节吧,首先来看看游戏服务器(世界服务器)的主流程吧,代码如下: extern int main(i