|
From: Tyson D. <ty...@ty...> - 2001-01-24 06:17:25
|
On 23-Jan-2001, Ina Cheng <in...@st...> wrote:
> Hi,
>
> Since Tyson said it is very inconvenience to build ./server (due to
> the links to the xml and dynamic_linking directories), I've copied those
> directories to the webserver dir in my workspace and modified the
> Mmakefile so that I only have to type
>
> mmake GRADE=hlc.par.gc depend
> mmake GRADE=hlc.par.gc
>
> to build ./server.
>
> Tyson is thinking about cvs adding those 2 directories to `/webserver'.
> However, if anyone make changes to those 2 directories, it will cause
> double maintenance problem. To avoid this, maybe I can modify
> the makefile such that those directories are copied from the master
> copies ( extra/xml and extra/dynamic_linking ), but that will depend
> on the path of `/webserver' (Just like the Mmakefile in dynamic_linking,
> the BROWSER_DIR path depends on the location of dynamic_linking). So,
> what should I do?
I don't care too much about double update problems with these
directories. Leave a comment saying what date you checked out these
directories from the mercury repository, and we can use CVS to track any
changes.
I hope to work on proper installation routines for Mercury libraries
some time this year, and so hopefully when that is working we shouldn't
have to worry about these double update problems so often.
> Anyway, below is a new diff. The web_method_request and parameter structure
> has changed after taking into account compound types as well.
You should prepare a log message for this change.
> Index: Mmakefile
> ===================================================================
> RCS file: /cvsroot/quicksilver/webserver/Mmakefile,v
> retrieving revision 1.2
> diff -u -r1.2 Mmakefile
> --- Mmakefile 2000/11/20 17:11:38 1.2
> +++ Mmakefile 2001/01/23 06:40:32
> @@ -7,12 +7,27 @@
> MAIN_TARGET=server
>
> MMAKEFLAGS=
> -SUBDIRS=concurrency net stream server
> +SUBDIRS=xml dynamic_linking concurrency net stream server
>
> +# Use shared libraries, since they're needed for dynamic linking
> +MGNUCFLAGS += --pic-reg
> +MLFLAGS += --shared
> +
> +# Link in the `-ldl' library (this may not be needed on some systems)
> +MLLIBS += -ldl
>
> #----------------------------------------------------------------------#
> .PHONY: depend
> -depend: concurrency_depend stream_depend net_depend server_depend
> +depend: xml_depend dynamic_linking_depend concurrency_depend \
> + stream_depend net_depend server_depend
You should base this on a pattern substituion on SUBDIRS that appends
the _depend on the end.
> Index: server/Mmakefile
> ===================================================================
> RCS file: /cvsroot/quicksilver/webserver/server/Mmakefile,v
> retrieving revision 1.3
> diff -u -r1.3 Mmakefile
> --- server/Mmakefile 2000/11/24 14:21:17 1.3
> +++ server/Mmakefile 2001/01/23 06:40:32
> @@ -1,11 +1,23 @@
> -MAIN_TARGET=server
> +MAIN_TARGET=server libsoap_test_methods
>
> -include ../Mmake.params
This is useful, but you seem to have deleted it and not replaced it.
> Index: server/server.m
> ===================================================================
> RCS file: /cvsroot/quicksilver/webserver/server/server.m,v
> retrieving revision 1.4
> diff -u -r1.4 server.m
> --- server/server.m 2000/11/27 10:02:58 1.4
> +++ server/server.m 2001/01/23 06:40:32
> @@ -21,9 +21,13 @@
> :- import_module bool, char, exception, getopt.
> :- import_module int, list, require, std_util, string.
>
> +:- import_module soap.
> +:- import_module web.
> +:- import_module soap_test_methods.
> +
> main -->
> io__command_line_arguments(Args0),
> - { OptionOpts = option_ops(short_option, long_option, option_defaults)},
> + { OptionOpts = option_ops(short_option, long_option,
> option_defaults)},
> { getopt__process_options(OptionOpts, Args0, _Args, OptionsResult) },
> (
> { OptionsResult = ok(OptTable) },
> @@ -76,7 +80,14 @@
> { parse_request(RequestLines, RequestOrResponse) },
> (
> { RequestOrResponse = left(Request) },
> - generate_response(Request, Response)
> + (
> + { Request^cmd = post },
> + get_soapmessage(TCP, Request, Request0)
> + ;
> + { Request^cmd = get },
> + { Request0 = Request }
> + ),
> + generate_response(Request0, Response)
> ;
> { RequestOrResponse = right(Response) }
> ),
> @@ -115,12 +126,26 @@
>
> :- type request
> ---> request(
> - cmd :: string,
> + cmd :: cmd,
> uri :: string,
> version :: string,
> - headers :: list(string)
> + headers :: list(header),
> + body :: maybe(body)
> ).
>
>
> +:- type cmd
> + ---> get
> + ; post.
> +
> +:- type header
> + ---> header(
> + name :: string,
> + value :: string,
> + extra :: maybe(string)
> + ).
> +
> +:- type body == string.
> +
> :- pred parse_request(list(list(char))::in,
> either(request, response)::out) is det.
>
> @@ -131,12 +156,19 @@
> three_words(Cmd, URI, HTTP_Version, RequestLine, _),
> (
> Cmd \= [], URI \= [], HTTP_Version \= []
> - ->
> - Request = request(string__from_char_list(Cmd),
> + ->
> + parse_headers(RequestLines, Headers),
> + (
> + Cmd = ['P','O','S','T']
> + ->
> + Command = post
> + ;
> + Command = get
> + ),
> + Request = request(Command,
> string__from_char_list(URI),
> string__from_char_list(HTTP_Version),
> - list__map(string__from_char_list,
> - RequestLines)),
> + Headers, no),
> Either = left(Request)
> ;
> Response = response(501, [], no_body, yes),
> @@ -173,7 +205,91 @@
> { Word = [] }
> ).
>
> +:- pred parse_headers(list(list(char))::in, list(header)::out) is det.
> +
> +parse_headers([RequestLine | RequestLines], Headers) :-
> + three_words(Name, Value, Extra, RequestLine, _),
> + (
> + Extra \= []
> + ->
> + Extra0 = yes(string__from_char_list(Extra))
> + ;
> + Extra0 = no
> + ),
> + Header = header(string__from_char_list(Name),
> + string__from_char_list(Value),
> + Extra0),
> + parse_headers(RequestLines, Headers0),
> + Headers = [Header | Headers0].
> +
> +
> +%-----------------------------------------------------------------------------%+
> +:- pred get_soapmessage(S, request, request, io__state, io__state)
> + <= stream__duplex(S).
> +:- mode get_soapmessage(in, in, out, di, uo) is det.
> +
> +get_soapmessage(S, Request, Request0) -->
> + { get_content_length(Request^headers, Length) },
> + get_body(S, Length, SoapMessage),
> + { Request0 = request(Request^cmd,
> + Request^uri,
> + Request^version,
> + Request^headers,
> + yes(string__from_char_list(SoapMessage))) }.
This is indented a little far for my taste, try
{ Request0 = request(
Request^cmd,
Request^uri,
Request^version,
Request^headers,
yes(string__from_char_list(SoapMessage))
) }.
> +
> +% XXX should error message be produced if content length = 0
Content-length: 0
might be OK, but if you get to the end of the headers without finding
the content-length header, you want to throw an exception.
> +:- pred get_body(S, int, list(char), io__state, io__state)
> + <= stream__duplex(S).
> +:- mode get_body(in, in, out, di, uo) is det.
> +
> +% XXX what happen if there are still characters when length = 0
> +
> +get_body(S, Length, RequestLines) -->
> + stream__read_char(S, CharResult),
> + { Length0 = Length - 1 },
> + (
> + { Length0 = 0 },
> + { CharResult = ok(Char) }
> + ->
> + { RequestLines = [Char] }
> + % stream__write_string( S, "length is 0\n")
> + ;
> + { CharResult = error(Error) }
> + ->
> + { error(string__format("get_request: %s.", [s(Error)])) }
> + ;
> + { CharResult = ok(Char) }
> + ->
> + get_body(S, Length0, RequestLines0),
> + { RequestLines = [Char | RequestLines0] }
> + ;
> + % what about if char = '\r' '\n'
> + %assume { CharResult = eof }
> + { RequestLines = [] }
> + ).
>
It would be nice if you could look up the HTTP standard and see what it
says to do in these exceptional cases (even if you don't add code to do
it, you can say what needs to be done).
> +:- pred doc_foldl(pred(array(nsContent), ref(nsContent), nsElement,
> + string, nsList, list(string), list(string)),
> + array(nsContent), list(ref(nsContent)), nsElement, string, nsList,
> + list(string), list(string)).
> +:- mode doc_foldl(pred(in, in, in, in, in, in, out) is det, in, in,
> + in, in, in, in, out) is det.
> +
> +doc_foldl(_Pred, _, [], _, _, _, Acc, Acc).
> + % get_first_element(ElemName0, FirstElem),
> + % string__append("</", ElemName, FirstElem1),
> + % string__append(FirstElem1, ">", FirstElem2),
> + % list__reverse(Acc0, Acc1),
> + % Acc = [FirstElem2|Acc0].
> + % list__reverse(Acc2, Acc),
> + % my_delete(ElemName0, ElemName).
> +
> +
> +doc_foldl(Pred, ContentArray, [Ref|Refs], Method, Result, URIs,
> + Acc0, Acc) :-
> + doc_foldl(Pred, ContentArray, Refs, Method, Result, URIs,
> + Acc0, Acc1),
> + call(Pred, ContentArray, Ref, Method, Result, URIs,
> + Acc1, Acc).
> +
> +% :- pred insert_last(list(T)::in, T::in, list(T)::out) is det.
> +% insert_last([], T, [T]).
> +% insert_last([
> +
> +:- pred my_delete(list(T)::in, list(T)::out) is det.
> +my_delete([], []).
> +my_delete([_H|T], T).
There's a fair bit of commented out code at the bottom of this.
If it is just unfinished, add some comments to that effect.
> Index: server/web.m
> ===================================================================
> RCS file: web.m
> diff -N web.m
> --- /dev/null Mon Dec 11 17:26:27 2000
> +++ web.m Mon Jan 22 22:40:32 2001
> @@ -0,0 +1,480 @@
> +%---------------------------------------------------------------------------%
> +% Copyright (C) 2000, 2001 The University of Melbourne.
> +% This file may only be copied under the terms of the GNU Library General
> +% Public License - see the file COPYING.LIB in the Mercury distribution.
> +%---------------------------------------------------------------------------%
> +%
> +% File: web.m
> +% Author: inch
> +%
> +% Reference:
> +% http://www.w3.org/TR/SOAP
> +%
> +% This module handles remote procedure calls using SOAP protocol and
> +% generates corresponding responses. Depending on the name of the
> +% procedure call, a different method will be called.
Why is this called web?
It seems like a confusing name.
soap_rpc might be a better name.
Or maybe web_methods?
Anyway, I think the code is pretty near ready for commiting.
The question is -- should it be commited on a branch or on the main
development tree.
Pete, do you have an opinion on this?
--
Tyson Dowd #
# Surreal humour isn't everyone's cup of fur.
tr...@cs... #
http://www.cs.mu.oz.au/~trd #
|