Modified HTTPD

Started by grable, June 17, 2005, 09:42:56 AM

Previous topic - Next topic

grable

I tinkered with the included HTTPD some, and added a modified CGI:put-page into it, which executes an *.lsp file inside the current process and sends the result back.



should be a little faster then starting new processes, and scripts have full acces to the HTTPD context.

(reads <% %> and <%= %> tags.)



heres an example usage:
<%
(set 'page-title "Your IP")
%>
<html>
<head>
<title><%=page-title%></title>
</head>
<body>
<h1><%=page-title%>: <%=(first (net-peer HTTPD:connection))%></h1>
</body>
</html>


heres the ftp://anonymous@grable.cjb.net/HTTPD">modified HTTPD file for those interested.



this is just so much fun =)
grable

grable

#1
added support for query data with GET, but am having problems with POST.

which is wierd since its basicly the same happening on both GET and POST.

(puting data in QUERY_STRING env, and runing cgi-put-page)



maybe i need a fresh pair of eyes on this ;) hehehe



dev version with funky POST ftp://anonymous@grable.cjb.net/HTTPD_dev">HTTPD_dev
grable

Lutz

#2
Look into modules/cgi.lsp, perhaps it can help you. GET and POST isn't really the same. In a GET request variable/value pairs are encoded in the QUERY_STRING but in in a POST request you have to read more to get the post data. cgi.lsp handles this in a transparent fashion. It also contains a routine to do <% %> tag preprocessing, but your approach to have it integrated in the httpd itself is probably the better way to do it.



Lutz

grable

#3
my bad ;) was just a pathing issue.. hehehe



ive updated the original ftp://anonymous@grable.cjb.net/HTTPD">HTTPD link, for those interested.
grable

grable

#4
Thats where i "borrowed" this idea from in the first place.. ;) hehehe



bit im just sending the POST data in QUERY_STRING.. thats probably not the right thing to do ? . maybe add a POST_STRING env or something?



am not that familiar with http and cgi.
grable

grable

#5
Well i think i solved it..  theres realy no need to use env variables when i have acess to the HTTPD context.. to i just put things in HTTPD:QUERY_STRING and HTTPD:POST_STRING when the data is present..



heres the recent examle (and previous url has again been updated)

il probaly revork this code, since it pretty much a hack right now to get it to work properly..


<%
(set 'page-title "Your IP")
%>
<html>
<head>
<title><%=page-title%></title>
</head>
<body>
<h1><%=page-title%>: <%=(first (net-peer HTTPD:connection))%></h1>
<hr>
QUERY_STRING: <%=HTTPD:QUERY_STRING%><br>
POST_STRING: <%=HTTPD:POST_STRING%><br>
<form method="POST" action="yourip.lsp?testing">
<input type="text" name="postdata" value="some random data">
<input type="submit">
</form>
</body>
</html>




btw lutz (the newlisp expert ;) , in the loop of the cgi-put-page that evals embeded parts i do this:
(while ...
   ...
   (context (sym file-name))
   (eval-string ...)
   (context HTTPD)
   ...
)
 ...
(delete (sym file-name))
 is this the correct way to use a context? or should i put it outside of the loop?
grable

Lutz

#6
Thats the right way to do it. Changing the context around the evaluation will protect httpd from stuff happening inside the evaluation. I think because of that same reason I left <% %> tage processing in cgi.lsp used by the spawned cgi process.



Your way of server-side processing is probably more efficient, but also brings the danger of doing something 'evil' to the httpd server. Bracketing in its own context will not protect against everything. Imagine code in the preprocessed page hangs in a loop, then the httpd server is dead ;)



Lutz

grable

#7
Ah.. k.. i was just wondering.. glad i understood it.. hehe


QuoteImagine code in the preprocessed page hangs in a loop, then the httpd server is dead ;)


hehehehe, yeah.. i thought about that, il just have to be very careful ;)



Although an infinite loop could potentialy happen with another process to, since the httpd will wait for its termination anyway.
grable

grable

#8
my hacked version of HTTPD now eats cookies =)



i merged the functions from CGI.lsp with HTTPD, so scripts have roughly the same interface.



script interface:
 # variables
HTTPD:QUERY_STRING  = raw query data
HTTPD:POST_STRING    = raw post data
HTTPD:COOKIES_STRING = raw cookies data
HTTPD:CONTENT_TYPE  = content type of script result (text/html is default)
HTTPD:PUT_COOKIE    = raw cookie data to send to client
HTTPD:PARAMS         = query & post data as (key value) pairs
HTTPD:COOKIES        = cookies data as (key value) pairs

# functions
(HTTPD:get-cookie "name")
(HTTPD:set-cookie "name" "value")
(HTTPD:set-cookie-ex "name" "value" "domain" "path")
(HTTPD:get-param "name")


HTTPD now does the same as CGI.lsp, eg it fill the PARAMS and COOKIES for you before execution of the script, allso you can have multiple cookies in one request.





example usage:
<%
(set 'visits (int (HTTPD:get-cookie "VISITS")))
(if (= visits nil) (set 'visits 1))
(HTTPD:set-cookie "VISITS" (+ visits 1))
%>
<html>
<head>
<title>Test Page</title>
</head>
<body>
<h1>Your IP: <%=(first (net-peer HTTPD:connection))%></h1>
<hr>
Number of visits using cookies: <%=visits%><br>
QUERY_STRING: <%=HTTPD:QUERY_STRING%><br>
POST_STRING: <%=HTTPD:POST_STRING%><br>
COOKIES_STRING: <%=HTTPD:COOKIES_STRING%><br>
<form method="POST" action="yourip.lsp?testing">
<input type="text" name="postdata" value="some random data">
<input type="submit">
</form>
</body>
</html>


hope someone else allso finds this useful =) i kinda like having full access to my server, and being able to do whatever i want with it .. hehe



ftp://anonymous@grable.cjb.net/HTTPD">newest version of HTTPD
grable

HPW

#9
Hi grable,



I have problems to access your FTP.

Can you offer another option or send it?
Hans-Peter

grable

#10
QuoteI have problems to access your FTP.

Can you offer another option or send it?


Its in the mail =)



the ftp is on 24/7 so it "should" work.. dunno why you cant get in..



theres no password for anonymous, so the first one should work,

but some browsers may complain so the second one is more "correct".



ftp://anonymous@grable.cjb.net/HTTPD">//ftp://anonymous@grable.cjb.net/HTTPD

ftp://anonymous@grable.cjb.net/HTTPD">//ftp://anonymous:@grable.cjb.net/HTTPD



if anyone else cant get it and wants me to send it, just speak up =)
grable

statik

#11
Very cool.
-statik

grable

#12
I soon found out that having everything in a single process isnt to good either :/



its was a little bit faster then spawning a new process..

bit it could stil only serve 1 client at a time.. so it now spawns

process again ;) LOL



although this time with proper "forking" using (process)

so its can serve many clients.



it sends the "control" code over the commandline, and loads the

html+newlisp template file and runs it... so the control code must send

the result to the client and close the socket. freeing the server up to do other things =)



allmost same interface as before, just removed the HTTPD context from the script

and i removed the old CGI way completly.



heres the updated files:

ftp://anonymous@grable.cjb.net/grb_httpd.lsp">grb_httpd.lsp

ftp://anonymous@grable.cjb.net/index.lsp">index.lsp



go here to test http://grable.cjb.net/">//http://grable.cjb.net/



UPDATE: forks regular file downloads as well, like images/etc.
grable

Lutz

#13
Very interesting, congratulations, I would love to see the code, but cannot connect to your ftp, can you email it to me? lutz@nuevatec.com, and put the word 'newLISP' in the subject line, so my spamfilter doesn't eat it :)



Lutz

grable

#14
Thanks lutz =)



their in the mail...



Since some people are having trouble geting in to my ftp, ive

put the files on the http server as well..



http://grable.cjb.net/grb_httpd.rar">//http://grable.cjb.net/grb_httpd.rar
grable