;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ______ __ _ _ _ _ _ _ _ ; ; /#####/\ /###| /#/\ /#/\ /#/\ /########/\ ; ; /#/\_\_\/ /#/|#| /#/\/ /#/\//#/\/ /#/\/ /#/\/ ; ; /#/\/ /#/ |#| /#/\/ /#/\//#/\/ /#/\/ /#/\/ ; ; /#####/\ /#/\/|#|/#/\/ /######/_/ /#/\/ /#/\/ ; ; /#/\_\_\/ /#/\/ |# #/\/ /#/\/ \#\ /#/\/ /#/\/ ; ; /#/\/ /#/\/ |##/\/ /#/\/ \#\ /#/\/_ /#/\/ ; ; /#/\/______/#/\/___|#/\/ /#/\/_____\#\//########/\/ ; ; /#################################################/\ ; ; \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\/ ; ; ; ;------------------------------------------------------------------------------- ; Project: small http file server ; Version: 1.0.0.0 ; Description: a smal http server that can handle the GET method only. ; Date: 15/10/08 ; Autor: enkoreaver@gmail.com ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; format PE Console entry start include '%fasminc%/win32a.inc' include '%fasminc%/macro/if.inc' MAX_QUEUE equ 100 ;max namber of pending connections BUFFER_SIZE equ 2048 ;max size of the header sended by the client MAX_URL_SIZE equ 1024 ;max size of url in the header sended SHOW_DETAILED_MSG equ TRUE ;set TRUE if want to see the full client message section '.data' data readable writeable wsa WSADATA port dd 80 szPause db "PAUSE",0 h404 db "HTTP/1.1 404 Not Found",13,10,"Server: EnkoHttpServer 1.0.0.0 ",13,10,13,10,"404 Not Found",13,10 .size = $ - h404 h200 db "HTTP/1.1 200 OK",13,10,"Server: EnkoHttpServer 1.0.0.0 ",13,10,"Allow: GET",13,10,13,10 .size = $ - h200 szRoot db "D:\Documentos\Enko\Assembly\Projects\httpServer",0 szSlashes db '/\',0 szSlash db '\',0 szTockens db " ",13,10,0 szError db "ERROR: %i",13,10,0 szDot db ".",0 szFileNotExists db "File Not Exists",13,10,0 szInt db "%i",0 szFile db "FILE: %s",13,10,0 szClient db "Client IP: %s",13,10,0 szRequest db "REQUEST: %s",13,10,0 szStatus db "STATUS: %s",13,10,0 szString db "%s",0 szEndLine db 13,10,0 .size = $ - szEndLine szBr db "
",0 szIndex db "index.html",0 szFileSended db "File sended ok",13,10,0 .size = $ - szBr wSocketVersion dd 0x0101 transmiteBuffer dd h200,h200.size,NULL,NULL thread dd ? peer dd ? peerAddr sockaddr_in sizePeerAddr dd sizeof.sockaddr_in sock dd ? sock_addr sockaddr_in szBuffer db 32 dup ? szIp db 16 dup ? section '.code' code readable executable start: ;inti the socket invoke WSAStartup, [wSocketVersion], wsa invoke socket,AF_INET,SOCK_STREAM,NULL mov [sock],eax mov [sock_addr.sin_family], AF_INET invoke htons,[port] mov [sock_addr.sin_port],ax mov [sock_addr.sin_addr],NULL invoke bind, [sock], sock_addr,sizeof.sockaddr_in .if eax <> 0 invoke WSAGetLastError cinvoke printf, szError, eax .endif invoke listen, [sock],MAX_QUEUE accepted: ;socket listening invoke accept, [sock],peerAddr,sizePeerAddr mov [peer],eax stdcall ipToString,[peerAddr.sin_addr],szIp cinvoke printf, szClient,szIp ;new thread for each connection invoke CreateThread, NULL,NULL, resolveConnection,[peer],NULL,NULL jmp accepted invoke ExitProcess,0 ;the connection manager proc resolveConnection, lpParam local lpeer: DWORD, lbuffer: DWORD, lurl: DWORD, lfile: DWORD mov eax, [lpParam] mov [lpeer],eax cinvoke malloc, BUFFER_SIZE mov [lbuffer],eax invoke recv, [lpeer],[lbuffer],BUFFER_SIZE,0 ;if there is a message then continue .if eax <> 0 mov ebx,[lbuffer] mov byte [ebx+eax],0 .if SHOW_DETAILED_MSG cinvoke printf,szRequest, [lbuffer] .endif cinvoke strtok, [lbuffer], szTockens .if eax <> 0 ;handling the GET message .if dword[eax] = "GET" ;url sring allocation ;getting the URL from GET message cinvoke malloc, MAX_URL_SIZE mov [lurl],eax cinvoke strcpy, [lurl],szRoot cinvoke strtok, NULL, szTockens cinvoke strcat,[lurl],eax mov ebx,eax cinvoke strlen, eax mov edx,eax dec edx .repeat dec eax cmp byte[ebx+eax],"/" .if ZERO? mov byte[ebx+eax],"\" .endif .until eax = 0 .if byte[ebx+edx] = "\" cinvoke strcat,[lurl],szIndex .endif cinvoke printf, szFile, [lurl] ;opening the file to send to browser invoke CreateFile,[lurl],GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,0 ;file exists, sending,,,, .if eax <> INVALID_HANDLE_VALUE mov [lfile],eax invoke GetFileSize, [lfile],NULL invoke TransmitFile, [lpeer],[lfile],eax,NULL,NULL,transmiteBuffer,NULL .if eax cinvoke printf, szStatus, szFileSended .endif invoke CloseHandle, [lfile] .else cinvoke printf, szStatus, szFileNotExists invoke send, [lpeer], h404, h404.size, 0 .endif cinvoke free, [lurl] .endif .endif .endif .exit: cinvoke free, [lbuffer] invoke CloseHandle, [lpeer] invoke ExitThread ret endp ;convert DWORD ip to ip sring for displaying later proc ipToString, ip, string local buffer: DWORD mov ebx, [ip] mov esi,4 mov eax,[string] mov byte [eax],0 .repeat xor eax,eax mov al,bl cinvoke sprintf,[buffer],szInt,eax cinvoke strcat,[string],[buffer] cinvoke strcat,[string],szDot shr ebx,8 dec esi .until esi=0 cinvoke strlen, [string] mov ebx, [string] mov byte[ebx+eax-1],0 mov byte[buffer],0 ret endp section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL',\ msvcrt,'msvcrt.dll',\ wsock32, 'WSOCK32.DLL' include '%fasminc%\apia\kernel32.inc' include '%fasminc%\apia\user32.inc' include '%fasminc%\apia\msvcrt.inc' include '%fasminc%\apia\wsock32.inc'