+cookie_lexer.cmo: cookie_lexer.cmi
+cookie_lexer.cmx: cookie_lexer.cmi
http_common.cmo: http_types.cmi http_constants.cmi http_common.cmi
http_common.cmx: http_types.cmx http_constants.cmx http_common.cmi
http_constants.cmo: http_constants.cmi
http_misc.cmo: http_types.cmi http_misc.cmi
http_misc.cmx: http_types.cmx http_misc.cmi
http_parser.cmo: http_types.cmi http_parser_sanity.cmi http_constants.cmi \
- http_common.cmi http_parser.cmi
+ http_common.cmi cookie_lexer.cmi http_parser.cmi
http_parser.cmx: http_types.cmx http_parser_sanity.cmx http_constants.cmx \
- http_common.cmx http_parser.cmi
+ http_common.cmx cookie_lexer.cmx http_parser.cmi
http_parser_sanity.cmo: http_types.cmi http_constants.cmi \
http_parser_sanity.cmi
http_parser_sanity.cmx: http_types.cmx http_constants.cmx \
export SHELL=/bin/bash
MODULES = \
- http_constants http_types http_parser_sanity http_misc http_common \
- http_tcp_server http_parser http_message http_request http_daemon \
- http_response http_user_agent
+ http_constants \
+ http_types \
+ http_parser_sanity \
+ http_misc \
+ http_common \
+ http_tcp_server \
+ cookie_lexer \
+ http_parser \
+ http_message \
+ http_request \
+ http_daemon \
+ http_response \
+ http_user_agent \
+ $(NULL)
THREADED_SRV = http_threaded_tcp_server
MODULES_MT = $(patsubst http_tcp_server, mt/$(THREADED_SRV) http_tcp_server, $(MODULES))
depend:
$(OCAMLDEP) *.ml *.mli > .depend
+%.ml: %.mll
+ $(OCAMLLEX) $<
%.cmi: %.mli
$(OCAMLC) -c $<
%.cmo: %.ml %.cmi
OCAMLC = $(OCAMLFIND) ocamlc $(COMMON_FLAGS)
OCAMLOPT = $(OCAMLFIND) ocamlopt $(COMMON_FLAGS)
OCAMLDEP = $(OCAMLFIND) ocamldep $(COMMON_FLAGS)
+OCAMLLEX = ocamllex
OCAMLDOC := \
ocamldoc -stars \
$(shell $(OCAMLFIND) query -i-format unix) \
--- /dev/null
+(*
+ OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
+
+ Copyright (C) <2002-2007> Stefano Zacchiroli <zack@cs.unibo.it>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation, version 2.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+*)
+
+type cookie_token =
+ [ `QSTRING of string
+ | `SEP
+ | `TOKEN of string
+ | `ASSIGN
+ | `EOF ]
+
+val token : Lexing.lexbuf -> cookie_token
+
* send internally generated headers as lowercase strings, for consistency
with headers generated via setXXX methods
+ * added preliminary support for cookies (new "cookies" method added to an
+ http_request, cookies are parsed upon request creation if a "Cookie:"
+ header has been received)
- -- Stefano Zacchiroli <zack@debian.org> Wed, 24 Jan 2007 10:09:12 +0100
+ -- Stefano Zacchiroli <zack@debian.org> Mon, 29 Jan 2007 11:43:40 +0100
ocaml-http (0.1.3-3) UNRELEASED; urgency=low
-
(*
OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
- Copyright (C) <2002-2004> Stefano Zacchiroli <zack@cs.unibo.it>
+ Copyright (C) <2002-2007> Stefano Zacchiroli <zack@cs.unibo.it>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
(sprintf "request ALL params = %s\n"
(String.concat ";"
(List.map (fun (h,v) -> String.concat "=" [h;v]) req#params))) ^
+ (sprintf "cookies = %s\n"
+ (match req#cookies with
+ | None ->
+ "NO COOKIES "
+ ^ (if req#hasHeader ~name:"cookie"
+ then "('Cookie:' header was '" ^ req#header ~name:"cookie" ^ "')"
+ else "(No 'Cookie:' header received)")
+ | Some cookies ->
+ (String.concat ";"
+ (List.map (fun (n,v) -> String.concat "=" [n;v]) cookies)))) ^
(sprintf "request BODY = '%s'\n\n" req#body)
in
Http_daemon.respond ~code:(`Code 200) ~body: str outchan
in
parse_headers' []
+let parse_cookies raw_cookies =
+ prerr_endline ("raw cookies: '" ^ raw_cookies ^ "'");
+ let tokens =
+ let lexbuf = Lexing.from_string raw_cookies in
+ let rec aux acc =
+ match Cookie_lexer.token lexbuf with
+ | `EOF -> acc
+ | token -> aux (token :: acc)
+ in
+ List.rev (aux [])
+ in
+ let rec aux = function
+ | [ `TOKEN n ; `ASSIGN ; (`TOKEN v | `QSTRING v) ] ->
+ prerr_endline ("found cookie " ^ n ^ " " ^ v);
+ [ (n,v) ]
+ | `TOKEN n :: `ASSIGN :: (`TOKEN v | `QSTRING v) :: `SEP :: tl ->
+ prerr_endline ("found cookie " ^ n ^ " " ^ v);
+ (n,v) :: aux tl
+ | _ -> raise (Malformed_cookies raw_cookies)
+ in
+ aux tokens
+
let parse_request ic =
let (meth, uri, version) = parse_request_fst_line ic in
let path = parse_path uri in
@raise Invalid_header if a not well formed header is encountered *)
val parse_headers: in_channel -> (string * string) list
+ (** parse a Cookie header, extracting an associative list <attribute name,
+ * attribute value>. See RFC 2965
+ * @param raw_cookies: value of a "Cookies:" header
+ * @return a list of pairs cookie_name * cookie_value
+ * @raise Malformed_cookies *)
+val parse_cookies: string -> (string * string) list
+
(** given an input channel, reads from it a GET HTTP request and
@return a pair <path, query_params> where path is a string representing the
requested path and query_params is a list of pairs <name, value> (the GET
-
(*
OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
- Copyright (C) <2002-2005> Stefano Zacchiroli <zack@cs.unibo.it>
+ Copyright (C) <2002-2007> Stefano Zacchiroli <zack@cs.unibo.it>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as
in
(headers, body))
in
+ let cookies =
+ try
+ let _hdr, raw_cookies =
+ List.find
+ (fun (hdr, _cookie) -> String.lowercase hdr = "cookie")
+ headers
+ in
+ Some (Http_parser.parse_cookies raw_cookies)
+ with
+ | Not_found -> None
+ | Malformed_cookies _ -> None
+ in
let query_post_params =
match meth with
| `POST ->
method params_GET = query_get_params
method params_POST = query_post_params
+ method cookies = cookies
+
method private fstLineToString =
let method_string = string_of_method self#meth in
match self#version with
-
(*
OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
- Copyright (C) <2002-2005> Stefano Zacchiroli <zack@cs.unibo.it>
+ Copyright (C) <2002-2007> Stefano Zacchiroli <zack@cs.unibo.it>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as
-
(*
OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
- Copyright (C) <2002-2005> Stefano Zacchiroli <zack@cs.unibo.it>
+ Copyright (C) <2002-2007> Stefano Zacchiroli <zack@cs.unibo.it>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as
exception Malformed_query of string
exception Malformed_query_part of string * string
exception Malformed_request_URI of string
+exception Malformed_cookies of string
exception Malformed_request of string
exception Malformed_response of string
exception Param_not_found of string
method params: (string * string) list
method params_GET: (string * string) list
method params_POST: (string * string) list
+ method cookies: (string * string) list option
method authorization: auth_info option
end
-
(*
OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
- Copyright (C) <2002-2005> Stefano Zacchiroli <zack@cs.unibo.it>
+ Copyright (C) <2002-2007> Stefano Zacchiroli <zack@cs.unibo.it>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as
(** invalid request URI encountered *)
exception Malformed_request_URI of string
+ (** malformed cookies *)
+exception Malformed_cookies of string
+
(** malformed request received *)
exception Malformed_request of string
(** @return the list of all parameter received via POST *)
method params_POST: (string * string) list
+ method cookies: (string * string) list option
+
(** @return authorization information, if given by the client *)
method authorization: auth_info option