file-responder improvements, plugin improvements

cvs
Slava Pestov 2004-09-02 20:40:34 +00:00
parent cb4c439646
commit a0c9095ff5
12 changed files with 117 additions and 63 deletions

View File

@ -1,8 +1,7 @@
- telnetd should use multitasking - TEST telnetd should use multitasking
- file-responder: Content-Length - quit responder breaks with multithreading
- HEAD request for file-responder - nicer way to combine two paths
- nicer way to combine two paths - icons for file responder
- icons for file responder
- -1.1 3 ^ shouldn't give a complex number - -1.1 3 ^ shouldn't give a complex number
- don't show listener on certain commands - don't show listener on certain commands
- inferior hangs - inferior hangs
@ -19,6 +18,7 @@
- introduce ifte* and ?str-head/?str-tail where appropriate - introduce ifte* and ?str-head/?str-tail where appropriate
- cwd, cd, pwd, dir., pwd. words - cwd, cd, pwd, dir., pwd. words
- namespace clone drops static var bindings - namespace clone drops static var bindings
- f usages. --> don't print all words
+ bignums: + bignums:
@ -100,7 +100,6 @@
+ httpd: + httpd:
- 'default responder' for when we go to root - 'default responder' for when we go to root
- quit responder breaks with multithreading
- wiki responder: - wiki responder:
- port to native - port to native
- text styles - text styles

View File

@ -18,19 +18,22 @@
VFSManager.waitForRequests(); VFSManager.waitForRequests();
FactorPlugin.eval(view, FactorPlugin.eval(view,
"\"" "\""
+ factor.FactorReader.charsToEscapes(buffer.path) + FactorReader.charsToEscapes(buffer.path)
+ "\" run-file"); + "\" run-file");
</CODE> </CODE>
</ACTION> </ACTION>
<ACTION NAME="factor-apropos"> <ACTION NAME="factor-apropos">
<CODE> <CODE>
if(textArea.selectionCount == 0) word = FactorPlugin.getWordAtCaret(textArea);
textArea.selectWord(); if(word == null)
FactorPlugin.eval(view, view.toolkit.beep();
"\"" else
+ factor.FactorReader.charsToEscapes( {
textArea.selectedText) FactorPlugin.eval(view,
+ "\" apropos."); "\""
+ FactorReader.charsToEscapes(word)
+ "\" apropos.");
}
</CODE> </CODE>
</ACTION> </ACTION>
<ACTION NAME="factor-see"> <ACTION NAME="factor-see">
@ -55,10 +58,11 @@
</ACTION> </ACTION>
<ACTION NAME="factor-insert-use"> <ACTION NAME="factor-insert-use">
<CODE> <CODE>
if(textArea.selectionCount == 0) word = FactorPlugin.getWordAtCaret(textArea);
textArea.selectWord(); if(word == null)
FactorPlugin.insertUseDialog(view, view.toolkit.beep();
textArea.selectedText); else
FactorPlugin.insertUseDialog(view,word);
</CODE> </CODE>
</ACTION> </ACTION>
</ACTIONS> </ACTIONS>

View File

@ -44,6 +44,13 @@ public class FactorPlugin extends EditPlugin
private static FactorInterpreter interp; private static FactorInterpreter interp;
//{{{ start() method
public void start()
{
BeanShell.eval(null,BeanShell.getNameSpace(),
"import factor.*;\nimport factor.jedit.*;\n");
} //}}}
//{{{ getInterpreter() method //{{{ getInterpreter() method
/** /**
* This can be called from the SideKick thread and must be thread safe. * This can be called from the SideKick thread and must be thread safe.

View File

@ -68,6 +68,8 @@ USE: wiki-responder
<responder> [ <responder> [
"file" "responder" set "file" "responder" set
[ file-responder ] "get" set [ file-responder ] "get" set
[ file-responder ] "post" set
[ file-responder ] "head" set
] extend "file" set ] extend "file" set
! <responder> [ ! <responder> [

View File

@ -33,6 +33,7 @@ USE: html
USE: httpd USE: httpd
USE: httpd-responder USE: httpd-responder
USE: kernel USE: kernel
USE: lists
USE: logging USE: logging
USE: namespaces USE: namespaces
USE: parser USE: parser
@ -40,18 +41,26 @@ USE: stack
USE: stdio USE: stdio
USE: streams USE: streams
USE: strings USE: strings
USE: unparser
: serving-path ( filename -- filename ) : serving-path ( filename -- filename )
f>"" "doc-root" get swap cat2 ; f>"" "doc-root" get swap cat2 ;
: file-header ( mime-type -- header )
"200 Document follows" swap response ;
: copy-and-close ( from -- ) : copy-and-close ( from -- )
[ dupd "stdio" get fcopy ] [ >r fclose r> rethrow ] catch ; [ dupd "stdio" get fcopy ] [ >r fclose r> rethrow ] catch ;
: file-response ( mime-type length -- )
[,
unparse "Content-Length" swons ,
"Content-Type" swons ,
,] "200 OK" response ;
: serve-static ( filename mime-type -- ) : serve-static ( filename mime-type -- )
file-header print <filebr> "stdio" get fcopy ; over file-length file-response "method" get "head" = [
drop
] [
<filebr> "stdio" get copy-and-close
] ifte ;
: serve-file ( filename -- ) : serve-file ( filename -- )
dup mime-type dup "application/x-factor-server-page" = [ dup mime-type dup "application/x-factor-server-page" = [
@ -66,7 +75,12 @@ USE: strings
%> redirect ; %> redirect ;
: list-directory ( directory -- ) : list-directory ( directory -- )
serving-html dup [ directory. ] simple-html-document ; serving-html
"method" get "head" = [
drop
] [
dup [ directory. ] simple-html-document
] ifte ;
: serve-directory ( filename -- ) : serve-directory ( filename -- )
"/" ?str-tail [ "/" ?str-tail [
@ -82,13 +96,13 @@ USE: strings
: serve-object ( filename -- ) : serve-object ( filename -- )
dup directory? [ serve-directory ] [ serve-file ] ifte ; dup directory? [ serve-directory ] [ serve-file ] ifte ;
: file-responder ( filename -- ) : file-responder ( filename method -- )
"doc-root" get [ "doc-root" get [
serving-path dup exists? [ serving-path dup exists? [
serve-object serve-object
] [ ] [
drop "404 not found" httpd-error 2drop "404 not found" httpd-error
] ifte ] ifte
] [ ] [
drop "404 doc-root not set" httpd-error 2drop "404 doc-root not set" httpd-error
] ifte ; ] ifte ;

View File

@ -42,30 +42,42 @@ USE: unparser
USE: url-encoding USE: url-encoding
: response ( msg content-type -- response ) : print-header ( alist -- )
swap <% "HTTP/1.0 " % % "\nContent-Type: " % % "\n" % %> ; [ unswons write ": " write url-encode print ] each ;
: response-write ( msg content-type -- ) : response ( header msg -- )
response print ; "HTTP/1.0 " write print print-header ;
: error-body ( error -- body ) : error-body ( error -- body )
"\n<html><body><h1>" swap "</h1></body></html>" cat3 ; "<html><body><h1>" swap "</h1></body></html>" cat3 print ;
: error-head ( error -- )
dup log-error
[ [ "Content-Type" | "text/html" ] ] over response ;
: httpd-error ( error -- ) : httpd-error ( error -- )
dup log-error #! This must be run from handle-request
<% dup "text/html" response % error-body % %> print ; error-head
"head" "method" get = [ terpri error-body ] unless ;
: bad-request ( -- )
[
! Make httpd-error print a body
"get" "method" set
"400 Bad request" httpd-error
] with-scope ;
: serving-html ( -- ) : serving-html ( -- )
"200 Document follows" "text/html" response print ; [ [ "Content-Type" | "text/html" ] ]
"200 Document follows" response terpri ;
: serving-text ( -- ) : serving-text ( -- )
"200 Document follows" "text/plain" response print ; [ [ "Content-Type" | "text/plain" ] ]
"200 Document follows" response terpri ;
: redirect ( to -- ) : redirect ( to -- )
"301 Moved Permanently" "text/plain" response write "Location" swons unit
"Location: " write write "301 Moved Permanently" response terpri ;
terpri terpri
"The resource has moved." print ;
: header-line ( alist line -- alist ) : header-line ( alist line -- alist )
": " split1 dup [ transp acons ] [ 2drop ] ifte ; ": " split1 dup [ transp acons ] [ 2drop ] ifte ;
@ -107,7 +119,3 @@ USE: url-encoding
read-header dup "header" set read-header dup "header" set
dup log-user-agent dup log-user-agent
read-post-request "response" set ; read-post-request "response" set ;
: with-request ( url quot -- )
#! The quotation is called with the URL on the stack.
[ swap prepare-url swap prepare-header call ] with-scope ;

View File

@ -30,6 +30,7 @@ USE: combinators
USE: errors USE: errors
USE: httpd-responder USE: httpd-responder
USE: kernel USE: kernel
USE: lists
USE: logging USE: logging
USE: logic USE: logic
USE: namespaces USE: namespaces
@ -48,9 +49,6 @@ USE: url-encoding
drop "stdio" get drop "stdio" get
] ifte ; ] ifte ;
: bad-request ( -- )
"400 Bad request" httpd-error ;
: url>path ( uri -- path ) : url>path ( uri -- path )
url-decode dup "http://" str-head? dup [ url-decode dup "http://" str-head? dup [
"/" split1 f "" replace nip nip "/" split1 f "" replace nip nip
@ -61,22 +59,19 @@ USE: url-encoding
: secure-path ( path -- path ) : secure-path ( path -- path )
".." over str-contains? [ drop f ] when ; ".." over str-contains? [ drop f ] when ;
: get-request ( url -- ) : request-method ( cmd -- method )
[ "get" swap serve-responder ] with-request ; [
[ "GET" | "get" ]
[ "POST" | "post" ]
[ "HEAD" | "head" ]
] assoc [ "bad" ] unless* ;
: post-request ( url -- ) : (handle-request) ( arg cmd -- url method )
[ "post" swap serve-responder ] with-request ; request-method dup "method" set swap
prepare-url prepare-header ;
: head-request ( url -- )
[ "head" swap serve-responder ] with-request ;
: handle-request ( arg cmd -- ) : handle-request ( arg cmd -- )
[ [ (handle-request) serve-responder ] with-scope ;
[ "GET" = ] [ drop get-request ]
[ "POST" = ] [ drop post-request ]
[ "HEAD" = ] [ drop head-request ]
[ drop t ] [ 2drop bad-request ]
] cond ;
: parse-request ( request -- ) : parse-request ( request -- )
dup log dup log

View File

@ -41,6 +41,7 @@ USE: strings
! Responders are called in a new namespace with these ! Responders are called in a new namespace with these
! variables: ! variables:
! - method -- one of get, post, or head.
! - request -- the entire URL requested, including responder ! - request -- the entire URL requested, including responder
! name ! name
! - raw-query -- raw query string ! - raw-query -- raw query string
@ -64,6 +65,10 @@ USE: strings
[ [
drop "HEAD method not implemented" httpd-error drop "HEAD method not implemented" httpd-error
] "head" set ] "head" set
( url -- )
[
drop bad-request
] "bad" set
] extend ; ] extend ;
: get-responder ( name -- responder ) : get-responder ( name -- responder )

View File

@ -57,3 +57,6 @@ USE: strings
<file> swap <file> <file> swap <file>
[ "java.io.File" ] "java.io.File" "renameTo" [ "java.io.File" ] "java.io.File" "renameTo"
jinvoke ; jinvoke ;
: file-length ( file -- size )
<file> [ ] "java.io.File" "length" jinvoke ;

View File

@ -42,3 +42,6 @@ USE: strings
: directory ( dir -- list ) : directory ( dir -- list )
#! List a directory. #! List a directory.
(directory) str-sort ; (directory) str-sort ;
: file-length ( file -- length )
stat dup [ cdr cdr car ] when ;

View File

@ -27,15 +27,16 @@
IN: telnetd IN: telnetd
USE: combinators USE: combinators
USE: continuations
USE: errors USE: errors
USE: interpreter USE: interpreter
USE: kernel
USE: logging USE: logging
USE: logic USE: logic
USE: namespaces USE: namespaces
USE: stack USE: stack
USE: stdio USE: stdio
USE: streams USE: streams
USE: threads
: telnet-client ( socket -- ) : telnet-client ( socket -- )
dup [ dup [
@ -45,6 +46,14 @@ USE: streams
interpreter-loop interpreter-loop
] with-stream ; ] with-stream ;
: telnet-connection ( socket -- )
#! We don't do multitasking in JFactor.
java? [
telnet-client
] [
[ telnet-client ] in-thread drop
] ifte ;
: quit-flag ( -- ? ) : quit-flag ( -- ? )
global [ "telnetd-quit-flag" get ] bind ; global [ "telnetd-quit-flag" get ] bind ;
@ -55,7 +64,7 @@ USE: streams
[ [
quit-flag not quit-flag not
] [ ] [
dup >r accept telnet-client r> dup >r accept telnet-connection r>
] while ; ] while ;
: telnetd ( port -- ) : telnetd ( port -- )

View File

@ -7,9 +7,14 @@ USE: namespaces
USE: stdio USE: stdio
USE: test USE: test
USE: url-encoding USE: url-encoding
USE: strings
USE: stack
USE: lists
[ "HTTP/1.0 404\nContent-Type: text/html\n" ] [ "HTTP/1.0 200 OK\nContent-Length: 12\nContent-Type: text/html\n" ]
[ "404" "text/html" response ] unit-test [
[ "text/html" 12 file-response ] with-string
] unit-test
[ 5430 ] [ 5430 ]
[ f "Content-Length: 5430" header-line content-length ] unit-test [ f "Content-Length: 5430" header-line content-length ] unit-test