X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2FDEVEL%2Focaml-http%2Fhttp_request.ml;h=e3bc95bc1f5666d060802723448bd5e178563de6;hb=ca9cd0aeee0ce78a891f7f6091ca8704231a446d;hp=c135c95b31059294582dd98161fcfde6e5525f31;hpb=b5703de4f7697426ebda94fce2558add7c4f0285;p=helm.git diff --git a/helm/DEVEL/ocaml-http/http_request.ml b/helm/DEVEL/ocaml-http/http_request.ml index c135c95b3..e3bc95bc1 100644 --- a/helm/DEVEL/ocaml-http/http_request.ml +++ b/helm/DEVEL/ocaml-http/http_request.ml @@ -19,19 +19,115 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) +open Printf;; + open Http_common;; open Http_types;; -class request ~path ~params ~clisockaddr = - let (addr, port) = Http_misc.explode_sockaddr clisockaddr in +let debug_dump_request path params = + debug_print ("request path = " ^ path); + debug_print ( + sprintf"request params = %s" + (String.concat ";" + (List.map (fun (h,v) -> String.concat "=" [h;v]) params))) + +exception Fallback;; (* used internally by request class *) + +class request ic = + let (meth, uri, version) = Http_parser.parse_request_fst_line ic in + let uri_str = Neturl.string_of_url uri in + let path = Http_parser.parse_path uri in + let query_get_params = Http_parser.parse_query_get_params uri in + let headers = Http_parser.parse_headers ic in (* trailing \r\n consumed! *) + let body = + (* TODO fallback on Transfer-Encoding if Content-Length isn't defined *) + if meth = `POST then + Buffer.contents + (try (* read only Content-Length bytes *) + let limit_raw = + (try + (snd (List.find + (fun (h,v) -> String.lowercase h = "content-length") headers)) + with Not_found -> raise Fallback) + in + let limit = + (try (* TODO supports only a maximum content-length of 1Gb *) + int_of_string limit_raw + with Failure "int_of_string" -> + raise (Invalid_header ("Content-Length: " ^ limit_raw))) + in + Http_misc.buf_of_inchan ~limit ic + with Fallback -> Http_misc.buf_of_inchan ic) (* read until EOF *) + else "" (* TODO empty body for methods other than POST, is what we want? *) + in + (* TODO brave assumption: when meth = `POST, Content-Type is + application/x-www-form-urlencoded and is therefore one-liner parsed as a GET + query *) + let query_post_params = + match meth with + | `POST -> Http_parser.split_query_params body + | _ -> [] + in + let params = query_post_params @ query_get_params in (* prefers POST params *) + let _ = debug_dump_request path params in + let (clisockaddr, srvsockaddr) = + (Http_misc.peername_of_in_channel ic, Http_misc.sockname_of_in_channel ic) + in + + object (self) + + inherit + Http_message.message ~body ~headers ~version ~clisockaddr ~srvsockaddr + + val params_tbl = + let tbl = Hashtbl.create (List.length params) in + List.iter (fun (n,v) -> Hashtbl.add tbl n v) params; + tbl + + method meth = meth + method uri = uri_str + method path = path + method param ?meth name = + (match (meth: meth option) with + | None -> + (try + Hashtbl.find params_tbl name + with Not_found -> raise (Param_not_found name)) + | Some `GET -> List.assoc name query_get_params + | Some `POST -> List.assoc name query_post_params) + method paramAll ?meth name = + (match (meth: meth option) with + | None -> List.rev (Hashtbl.find_all params_tbl name) + | Some `GET -> Http_misc.list_assoc_all name query_get_params + | Some `POST -> Http_misc.list_assoc_all name query_post_params) + method params = params + method params_GET = query_get_params + method params_POST = query_post_params + + method private fstLineToString = + sprintf "%s %s %s" + (string_of_method self#meth) self#uri (string_of_version self#version) + + end + +(* (* OLD IMPLEMENTATION *) +class request + ~body ~headers ~version ~meth ~uri + ~clisockaddr ~srvsockaddr + ~path ~params + () + = object (self) + + inherit + Http_message.message ~body ~headers ~version ~clisockaddr ~srvsockaddr + val params_tbl = let tbl = Hashtbl.create (List.length params) in List.iter (fun (n,v) -> Hashtbl.add tbl n v) params; tbl - val uri = - path ^ "?" ^ - (String.concat "&" (List.map (fun (n, v) -> n ^ "=" ^ v) params)) + + method meth = meth method uri = uri method path = path method param name = @@ -41,8 +137,14 @@ class request ~path ~params ~clisockaddr = raise (Param_not_found name) method paramAll name = List.rev (Hashtbl.find_all params_tbl name) method params = params - method clientSockaddr = clisockaddr - method clientAddr = addr - method clientPort = port + + method private fstLineToString = + sprintf + "%s %s %s" + (string_of_method self#meth) + self#uri + (string_of_version self#version) + end +*)