flat assembler
Message board for the users of flat assembler.

Index > Projects and Ideas > Small http Server

Author
Thread Post new topic Reply to topic
Enko



Joined: 03 Apr 2007
Posts: 678
Location: Mar del Plata
Enko
Hy, this is a very simplistic http server that can handle the GET method.
The root directory is the same as the executable.

Acepted URLs:
if the url is a directory with index.html, you need to add a slash at the end. Example: http://localhost/mydir/, the server will look for a file called $szRoot/mydir/index.html
Any url with extension is acepted, example http://localhost/test.html
Wrong url: http://localhost/mydir , no file will be opened


SettingUP:
Edit szRoot to your executable path. Default: C:\httpServer
Edit port to any other, 80 default
Set SHOW_DETAILED_MSG to FALSE if you don't want to see the browser message
you will need to reassemble the source Razz.

known limitations
Theres only 150 lines of code, don't expect to much Smile
Perhaps no update will be added too.

Code:
; 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: 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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 sent by the client
MAX_URL_SIZE equ 1024   ;max size of url in the header send
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,"<HTML><BODY>404 Not Found</BODY></HTML>",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 "C:\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 "<br>",0
    szIndex     db "index.html",0
    szFileSent    db "File Sent 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, szFileSent
                    .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'
    

Coments are welcome.
Cheers


Description:
Download
Filename: httpServer.rar
Filesize: 10.78 KB
Downloaded: 570 Time(s)



Last edited by Enko on 28 Oct 2011, 21:43; edited 2 times in total
Post 09 Nov 2008, 05:03
View user's profile Send private message Reply with quote
drhowarddrfine



Joined: 10 Jul 2007
Posts: 535
drhowarddrfine
fwiw, <html> and <body> are optional and even those can be removed.
Post 09 Nov 2008, 17:08
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
With Quetannon
Quote:
Connected.
GET /../../../../../../../../../../../../boot.ini
HTTP/1.1 200 OK
Server: EnkoHttpServer 1.0.0.0
Allow: GET

[boot loader]
timeout=10
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect
Disconnected.

In the console:
Quote:
Client IP: 127.0.0.1
REQUEST: GET /../../../../../../../../../../../../boot.ini

FILE: D:\Documentos\Enko\Assembly\Projects\httpServer\..\..\..\..\..\..\..\..\..
\..\..\..\boot.ini
STATUS: File sended ok

(Since I wasn't able to recompile I replicated your path in my computer since I also have a D volume and copied boot.ini to D just to simulate the case in which the root is on the system volume)

Could you upload msvcrt.inc? It is not included in the official package.

PS: BTW, sended != sent Wink
Post 09 Nov 2008, 17:42
View user's profile Send private message Reply with quote
Enko



Joined: 03 Apr 2007
Posts: 678
Location: Mar del Plata
Enko
Quote:

(Since I wasn't able to recompile I replicated your path in my computer since I also have a D volume and copied boot.ini to D just to simulate the case in which the root is on the system volume)

Changed defaul directory to C:\httpServer Smile



Quote:

PS: BTW, sended != sent Wink

Replaced :$

Quote:

fwiw, <html> and <body> are optional and even those can be removed.

thanks for the advise Smile, I just leave them for any case... Razz

Quote:
Could you upload msvcrt.inc? It is not included in the official package.

Uploaded, the file was maded using dll2inc. Razz

Thanks evryone for replays.
Post 09 Nov 2008, 17:57
View user's profile Send private message Reply with quote
SFeLi



Joined: 03 Nov 2004
Posts: 140
Location: Severodvinsk, Russia
SFeLi
Doesn’t work for me (WARNING: tested on Windows 98!). CreateThread fails because you provided NULL for lpThreadId. TransmitFile is supported in Win2kPro+ only Sad.
In proc ipToString: cinvoke sprintf,[buffer],szInt,eax. I don’t know how does this work for you. It supplies a value of the buffer for sprintf, so it ends up with access violation. Why don’t just remove this function at all and use inet_ntoa?
include '%fasminc%\apia\kernel32.inc' (etc.) should be include 'api/kernel32.inc' for the latest fasm.
Post 09 Nov 2008, 19:10
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Enko



Joined: 03 Apr 2007
Posts: 678
Location: Mar del Plata
Enko
I run it on WinXP SP2, work fine. Dont´t have win98 to test it Sad
Tested using localhost and accesing using my connection IP from another pc via internet.
Quote:

In proc ipToString: cinvoke sprintf,[buffer],szInt,eax. I don’t know how does this work for you. It supplies a value of the buffer for sprintf, so it ends up with access violation

Seems that malloc function of msvcrt.dll fails on Win98 :S
Post 09 Nov 2008, 20:54
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
Enko,

CreateThread() easily leads to DoS Wink. QueueUserWorkItem()?
Post 09 Nov 2008, 21:04
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.