flat assembler
Message board for the users of flat assembler.
Index
> Windows > HTTP FIle server? Goto page 1, 2 Next |
Author |
|
OzzY 12 Aug 2007, 21:49
Does anyone have any clue on how to build a simple HTTP File Server, where files are stored at share/ and people can download them from their browsers by accessing http://ip?
Thanks |
|||
12 Aug 2007, 21:49 |
|
vid 12 Aug 2007, 22:51
Do you have TCP/IP implementation you can use, and you only need HTTP on top of it?
If no, then you will probably have to write LOT of code, too much i quess |
|||
12 Aug 2007, 22:51 |
|
vid 13 Aug 2007, 00:47
|
|||
13 Aug 2007, 00:47 |
|
Chewy509 13 Aug 2007, 01:47
HTTP is pretty easy if you have a complete TCP/IP and socket implementation to use.
In the past I have seen a very simple HTTP server implemented in about 50 lines of Perl. However hunting the 'net can't find it. I did find the following however: http://www.ibm.com/developerworks/library/wa-ltwebserv/index.html which contains a few links to smallish HTTP servers... Maybe you could use those as the basis? |
|||
13 Aug 2007, 01:47 |
|
drhowarddrfine 15 Aug 2007, 01:48
Look into lighttpd
|
|||
15 Aug 2007, 01:48 |
|
r22 15 Aug 2007, 03:28
I'm currently working on a HTTP server that has a simple dll interface to post and receive data from a dll. The purpose being, processor intensive tasks (db queries then parsing the result set, mathematical problem solving, file conversions, etc.) are best served by native code then script or VM (jsp, php, perl etc.). While CGI has a way to fork out to executables I think a more streamlined method is worth developing.
Having a server that takes a POSTed ASM file compiles it and returns the EXE/OBJ/DLL would be interesting, and useful, and possibly a security risk. ON TOPIC portion of post: While the HTTP protocol is relatively simple (being plain text and having a small subset of commands) implementing a reliable HTTP file server using winsock isn't. For an HTTP server you need - A stable Listen -> Accept -> Request loop - Forking the Accept(ed) socket to another thread works well, but if your not familiar with threading (CreateThread api) then it just adds another level of complexity. - To serve a directory listing where you can download files you'd need to use the file api and recursively tranverse the folder and sub folders of whatever directory you'd like to be your WWWROOT and compile a list of those file pathes and names, then create a HTML document with links. - Now you need to parse incoming HTTP requests and have a RECV_TIMEOUT set on the socket using (setsockopt api) if you don't have this, connections that don't send any data will be able to DoS, hang or cause memory leaks on your server. Unless you use WSA (asynchronous sockets) which add another level of complication if your not familiar with them. - Finally you need to read the file that you parsed out of the HTTP header sent to your server and write it to the socket after a properly formated HTTP reply header. - More specifically Ozzy wants to serve files over HTTP so he'd need to research (or packet sniff) the correct header attributes like content type, chunking and/or content length. - Ignoring security and configuration options for the server would help developement time. But you'd end up with something only suitable for personal use. CALL [Calculate_PI_To_Final_Digit] MOV [Rant],eax RET 0 |
|||
15 Aug 2007, 03:28 |
|
gunblade 15 Aug 2007, 21:49
Code: format PE console use32 entry start PORT = 80 include '%fasminc%\win32a.inc' macro print msg,msglen { common invoke WriteConsole,[stdout],msg,msglen,NULL,NULL } macro tcpsend msg,msglen { common invoke send,[peer],msg,msglen,NULL } section '.code' code readable executable start: invoke GetStdHandle,STD_OUTPUT_HANDLE mov [stdout],eax invoke WSAStartup,0101h,wsadata mov [port], PORT invoke socket,AF_INET,SOCK_STREAM,NULL mov [sockfd], eax mov eax, [port] and eax, 0xffff ror ax, 8 mov word [bindparms+2], ax invoke bind,[sockfd],bindparms,16 invoke listen,[sockfd],50 acceptit: invoke accept,[sockfd],peeraddr,sixteen mov dword [peer], eax invoke recv,[peer],buffer,bufferlen,0 mov ebx, buffer cmp dword [ebx], 'GET ' je .1 jmp endpeer .1: xor ecx, ecx inc ebx cmp byte [ebx], '/' je @f jmp .1 .2: @@: inc ebx cmp byte [ebx], ' ' je @f cmp byte [ebx], '%' je .hex mov al, [ebx] mov [buffer+ecx], al inc ecx jmp @b @@: mov byte [buffer+ecx], 0 cmp ecx, 0 jne @f mov dword [buffer], 'inde' mov dword [buffer+4], 'x.ht' mov word [buffer+8], 'ml' mov byte [buffer+10], 0 jmp @f .hex: inc ebx mov dx, [ebx] mov word [fd], dx mov word [fd+2], 0 mov edi, fd push ebx mov ebx, 16 call StrToInt pop ebx mov [buffer+ecx], al inc ebx inc ecx jmp .2 @@: invoke CreateFile,buffer,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL cmp eax, 0ffffffffh jne @f tcpsend h404,h404.len jmp endpeer @@: mov [fd], eax invoke TransmitFile,[peer],[fd],0,0,NULL,transmitbuffer,NULL invoke CloseHandle,[fd] endpeer: invoke CloseHandle,[peer] jmp acceptit exit: call WSACleanup invoke ExitProcess,0 IntToStr: ; eax = number, ebx = base, edi = buffer push ecx edx xor ecx,ecx .new: xor edx,edx div ebx push edx inc ecx test eax,eax jnz .new .loop: pop eax add al,30h cmp al,'9' jng .ok add al,7 .ok: stosb loop .loop mov al,0 stosb pop edx ecx ret StrToInt: ; edi = buffer, ebx = base push edx edi xor eax,eax xor edx,edx .loop: mov dl,byte [edi] test dl,dl jz .end imul eax,ebx sub dl,'0' cmp dl,9 jle .ok sub dl,7 .ok: add eax,edx inc edi jmp .loop .end: pop edi edx ret section '.data' data readable writeable h404 db 'HTTP/1.1 404 Not Found',13,10,13,10,'<HTML><BODY>404 Not Found</BODY></HTML>',10,13 .len = $ - h404 h200 db 'HTTP/1.1 200 OK',13,10,13,10 .len = $ - h200 transmitbuffer dd h200,h200.len,NULL,NULL bindparms dw 2, 0 dd 0, 0, 0 wsadata WSADATA stdout rd 1 peeraddr rb 16 port rd 1 strlen rd 1 multiplier rd 1 integer rd 1 sixteen dd 16 ten dd 10 sockfd rd 1 peer rd 1 fd rd 1 fdlen rd 1 buffer rb 512 bufferlen = $ - buffer section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ winsock,'WSOCK32.DLL',\ mswsock,'MSWSOCK.DLL' import kernel,\ GetStdHandle,'GetStdHandle',\ ExitProcess,'ExitProcess',\ WriteConsole,'WriteConsoleA',\ CreateFile,'CreateFileA',\ CloseHandle,'CloseHandle',\ GetCommandLine,'GetCommandLineA' import winsock,\ WSAStartup,'WSAStartup',\ WSACleanup,'WSACleanup',\ WSAAsyncSelect,'WSAAsyncSelect',\ gethostbyname,'gethostbyname',\ socket,'socket',\ bind,'bind',\ listen,'listen',\ accept,'accept',\ connect,'connect',\ recv,'recv',\ send,'send',\ closesocket,'closesocket' import mswsock,\ TransmitFile,'TransmitFile' Some warnings: - It's ugly, and has no comments - It's not multithreaded, so only one connection at a time - To change port, you'll have to modify that constant at the top and re-assemble using fasm - those StrtoInt and IntToStr functions are not mine, i copied them from someone who posted them on this board, i'm sorry to whoever it was who wrote them, i keep forgetting your name Apart from that.. it gets the job done. I should really update it to use threads and such, but I rarely use it, i usually use the linux version (which this one was ported from), so thats gotten more of my attention. EDIT: Oh yeah, couple more things.. Run it from a command prompt, since it has no GUI. Also, the directory you run it from will be the root of the webserver. (eg: if you run it in C:\dir1, then to access c:\dir1\file.txt, you would use the address: http://127.0.0.1/file.txt). You can also of course do subdirectories, eg: http://127.0.0.1/dir2/file2.txt. And I believe this version of the httpd still has the horrible flaw of being able to do: http://127.0.0.1/../../someotherdir/yourprivatefiles.txt. This can be fixed by doing some further parsing of the URL, but I didnt need it for what i was using the httpd for, so i never implemented it. In the linux one, i was able to simply chroot() which doesnt allow you to go above a certain directory, so that worked fine, I dont think the same exists on windows though. So yeah, not to be used for hosting public stuff, unless your sure you have nothing of value or secretive on your computer.. I coded this because i needed an easy way to transfer stuff over the lan.. so it isnt secure in the slightest. It should also handle files with spaces fine.. The only thing is files over 2GB, i dont think i included large file support, so just use ftp or something Now that i remember, this code doesnt even send the size of the file in the header. This isnt a problem, you can still send files fine without saying how big they are, the server simply closes the connection when the file is finished sending, and the client understands that as the end of file. The only thing is that you wont have a progress bar on the client end, as the program will not know the size of the full file. |
|||
15 Aug 2007, 21:49 |
|
OzzY 16 Aug 2007, 17:46
Thanks gunblade! Your example works!
But I couldn't learn much, as you said this code is ugly. I'm trying to craft a little server like this in HLL, to see if it works. Until now, my server works this way: Browser sends: GET / HTTP/1.1 (and other stuff My server answers: HTTP/1.1 200 OK\r\n\r\n [data of index.html] Browser sends: GET file.zip HTTP/1.1 My server answers: HTTP/1.1 200 OK\r\n\r\n [data of file.zip] But unfortunately the index.html isn't showing on the browser. What did I do wrong? |
|||
16 Aug 2007, 17:46 |
|
gunblade 16 Aug 2007, 17:52
Could be several things.. you made sure you close the connection after sending the contents of index.html?
If it isnt that.. im not sure what it could be, you might want to get a network packet sniffer like wireshark, with which you would be able to look at the packet data, and make sure that you are actually sending what you think your sending.. But i still think the first thing to check is that you are closing the connection after sending the data. The client (browser) will create a new connection for each file it wants. If that doesnt fix it, you might have to post your code, as i cant think of any other reasons without actually seeing the code. |
|||
16 Aug 2007, 17:52 |
|
OzzY 16 Aug 2007, 18:23
Nevermind... I did it! Works now!
ButI did it in Tcl, as it's a very easy scripting language. Now, I understand the concept, I can do it in ASM. If anyone wants to see the Tcl code before I translate it to ASM, tell me, so I can post. |
|||
16 Aug 2007, 18:23 |
|
OzzY 16 Aug 2007, 18:31
And it doesn't have the security flaw ../../, because it strips everything before the name, like:
If the name is: /../something.txt it will strip to: something.txt and check if file exists, and if it exists it will send it! |
|||
16 Aug 2007, 18:31 |
|
OzzY 16 Aug 2007, 18:35
Now I have a problem:
It just sends text/ASCII files. I can't send binary files. Any idea? |
|||
16 Aug 2007, 18:35 |
|
gunblade 16 Aug 2007, 18:50
What do you mean you cant send binary? as in.. the browser simply displays the binary instead of actually downloading it?
|
|||
16 Aug 2007, 18:50 |
|
OzzY 16 Aug 2007, 19:09
No. It opens the download dialog, but it saves nothing.
|
|||
16 Aug 2007, 19:09 |
|
gunblade 16 Aug 2007, 19:21
I cant think why, the code might help if you dont mind uploading it. It's strange that text works but binary doesnt, but yeah, upload, and ill take a look.
|
|||
16 Aug 2007, 19:21 |
|
r22 17 Aug 2007, 00:50
Your Content-Type AND/OR content-length is probably wrong in your response HEADER.
Content-Type: application/octet-stream Should be used, this will allow you to send bytes ad binary data. Content-Length: 999999 should be the bytes of data your a sending Then client will try to receive these bytes to place them in a file. |
|||
17 Aug 2007, 00:50 |
|
OzzY 17 Aug 2007, 02:56
I made it!
The problem was that I was not configuring the socket channel to binary translation (that's Tcl especific feature). Now that I got it working in Tcl, I can try to make an ASM version. |
|||
17 Aug 2007, 02:56 |
|
0.1 27 Sep 2007, 09:18
I am waiting for ASM version ...
... and today is 7th day! |
|||
27 Sep 2007, 09:18 |
|
sleepsleep 01 Oct 2007, 22:23
maybe a lightweight soap server?
|
|||
01 Oct 2007, 22:23 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.