首页 > 代码库 > VB6之HTTP服务器的实现(二)

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 pipe109     ret = CreatePipe(hrp, hwp, sa, 0&)110     If ret = 0 Then111         Debug.Print "[HTTP-VBS]: CGI Exception, pipe failed"112         Exit Function113     End If114     115     si.cb = Len(si)116     si.hStdOutput = hwp117     si.hStdError = hwp118     si.dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES119     si.wShowWindow = SW_HIDE120     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 Then125         Debug.Print "[HTTP-VBS]: CGI Exception, create process failed"126         Exit Function127     End If128     129     read response from cgi130     Dim nobr As Long num of bytes read131     Dim lpbuff As String132     Dim szbuff(65536 * 100) As Byte133     Dim sum As Long134     sum = 0135     Call RtlZeroMemory(ByVal VarPtr(szbuff(0)), 65536 * 100)136     Do137         nobr = 0&138         lpbuff = String(1024, " ")139         If ReadFile(hrp, ByVal lpbuff, 1024&, nobr, ByVal 0&) Then140             Call RtlMoveMemory(ByVal VarPtr(szbuff(sum)), ByVal StrPtr(lpbuff), LenB(lpbuff))141             sum = sum + LenB(lpbuff)142         Else143             Exit Do144         End If145         Call CloseHandle(hwp)146     Loop147     Call CloseHandle(hrp)148     149     rep_state = 200150     ShellCGI = Left(szbuff, sum)151 End Function152 153 Private Function MakeEnvString(ByVal head As Object) As String154     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 page@lichmama</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会不会觉得邪恶):

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