]> matita.cs.unibo.it Git - helm.git/commitdiff
added support for "ancient" HTTP requests like "GET /foo"
authorStefano Zacchiroli <zack@upsilon.cc>
Fri, 10 Jan 2003 09:39:20 +0000 (09:39 +0000)
committerStefano Zacchiroli <zack@upsilon.cc>
Fri, 10 Jan 2003 09:39:20 +0000 (09:39 +0000)
helm/DEVEL/ocaml-http/debian/changelog
helm/DEVEL/ocaml-http/http_message.ml
helm/DEVEL/ocaml-http/http_message.mli
helm/DEVEL/ocaml-http/http_parser.ml
helm/DEVEL/ocaml-http/http_parser.mli
helm/DEVEL/ocaml-http/http_parser_sanity.ml
helm/DEVEL/ocaml-http/http_parser_sanity.mli
helm/DEVEL/ocaml-http/http_request.ml
helm/DEVEL/ocaml-http/http_response.ml
helm/DEVEL/ocaml-http/http_types.ml

index e8fddf21ec61a97c71c8b1ec56e738aabcef7837..cdf4c48f0321a38be2b3d471bd4d81f227b2dc29 100644 (file)
@@ -1,3 +1,11 @@
+ocaml-http (0.0.8) unstable; urgency=low
+
+  * Added support for "ancient" HTTP requests which specify no HTTP
+    version
+    - 'version' method on message now has type 'version option'
+
+ -- Stefano Zacchiroli <zack@debian.org>  Fri, 10 Jan 2003 10:36:53 +0100
+
 ocaml-http (0.0.7) unstable; urgency=low
 
   * Added support for POST requests
index 2de1e1cbe0dacd1768e458b2cd53a3453c897632..ad3f38b50addf63e0ec62f8833fbb22c049f7b19 100644 (file)
@@ -43,14 +43,14 @@ class virtual message ~body ~headers ~version ~clisockaddr ~srvsockaddr =
 
     val _contentsBuf = Buffer.create 1024
     val _headers = Hashtbl.create 11
-    val mutable _version: version = version
+    val mutable _version: version option = version
 
     initializer
       self#setBody body;
       self#addHeaders headers
 
     method version = _version
-    method setVersion v = _version <- v
+    method setVersion v = _version <- Some v
 
     method body = Buffer.contents _contentsBuf
     method setBody c =
index e3f06f03fd1a0ab44d1ed33505ffd7e39fb8a83a..9f730939b90ee885844ab92c6476d7e5003b99ee 100644 (file)
@@ -25,11 +25,11 @@ open Http_types;;
   @param entity body included in the message
   @param headers message headers shipped with the message *)
 class virtual message:
-  body: string -> headers: (string * string) list -> version: version ->
+  body: string -> headers: (string * string) list -> version: version option ->
   clisockaddr: Unix.sockaddr -> srvsockaddr: Unix.sockaddr ->
     object
 
-      method version: version
+      method version: version option
       method setVersion: version -> unit
 
       method body: string
index 52c84570c285fed86f4af115a83f226df65580b4..c8870ab186729fe29c313cf141ca67a9cbfbf69c 100644 (file)
@@ -98,14 +98,18 @@ let debug_dump_request path params =
 let parse_request_fst_line ic =
   let request_line = generic_input_line ~sep:crlf ~ic in
   debug_print (sprintf "HTTP request line (not yet parsed): %s" request_line);
-  match Pcre.split ~rex:pieces_sep request_line with
-  | [ meth_raw; uri_raw; http_version_raw ] ->
-      (try
+  try
+    (match Pcre.split ~rex:pieces_sep request_line with
+    | [ meth_raw; uri_raw ] ->  (* ancient HTTP request line *)
         (method_of_string meth_raw,                 (* method *)
         Http_parser_sanity.url_of_string uri_raw,   (* uri *)
-        version_of_string http_version_raw)         (* version *)
-      with Neturl.Malformed_URL -> raise (Malformed_request_URI uri_raw))
-  | _ -> raise (Malformed_request request_line)
+        None)                                       (* no version given *)
+    | [ meth_raw; uri_raw; http_version_raw ] ->  (* HTTP 1.{0,1} *)
+          (method_of_string meth_raw,                 (* method *)
+          Http_parser_sanity.url_of_string uri_raw,   (* uri *)
+          Some (version_of_string http_version_raw))  (* version *)
+    | _ -> raise (Malformed_request request_line))
+  with Malformed_URL url -> raise (Malformed_request_URI url)
 
 let parse_path uri = patch_empty_path (String.concat "/" (Neturl.url_path uri))
 let parse_query_get_params uri =
index cd42c79e52e27cbea9fc49d1259d06e57379e411..c2c5a71134dfe702289bfa9a08a9964973c50d01 100644 (file)
@@ -23,7 +23,7 @@ open Http_types;;
 
 val split_query_params: string -> (string * string) list
 
-val parse_request_fst_line: in_channel -> meth * Neturl.url * version
+val parse_request_fst_line: in_channel -> meth * Neturl.url * version option
 val parse_query_get_params: Neturl.url -> (string * string) list
 val parse_path: Neturl.url -> string
 val parse_headers: in_channel -> (string * string) list
index 19204e870ba75ac52ecda5616a990ebe72df11da..be92934690e44a76a8ad6df46701439fc18560ef 100644 (file)
@@ -84,6 +84,9 @@ let heal_header (name, value) =
   heal_header_name name;
   heal_header_value name
  
-let url_of_string = url_of_string request_uri_syntax
+let url_of_string s =
+  try
+    url_of_string request_uri_syntax s
+  with Neturl.Malformed_URL -> raise (Malformed_URL s)
 let string_of_url = Neturl.string_of_url
 
index 3076a42a62902d49c0a393d76733fb6d3e49add7..f421c76c79e145f49506d49074f0a4662c28e08a 100644 (file)
@@ -26,6 +26,8 @@ val heal_header: string * string -> unit
   (** remove heading and/or trailing LWS sequences as per RFC2616 *)
 val normalize_header_value: string -> string
 
+  (** parse an URL from a string.
+  @raise Malformed_URL if an invalid URL is encountered *)
 val url_of_string: string -> Neturl.url
 val string_of_url: Neturl.url -> string
 
index cf86018507077929d755693c1500d4c7294b128f..65cba9710d95a00e29fd5f4cea335c441c3f89d6 100644 (file)
@@ -38,31 +38,39 @@ class request ic =
   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 =
-    List.map  (* lowercase header names to ease lookups before having a request
-              object *)
-      (fun (h,v) -> (String.lowercase h, v))
-      (Http_parser.parse_headers ic) (* trailing \r\n consumed! *)
-  in
-  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
-              List.assoc "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? *)
+  let (headers, body) =
+    (match version with
+    | None -> [], ""  (* No version given, use request's 1st line only *)
+    | Some version -> (* Version specified, parse also headers and body *)
+        let headers =
+          List.map  (* lowercase header names to ease lookups before having a
+                    request object *)
+            (fun (h,v) -> (String.lowercase h, v))
+            (Http_parser.parse_headers ic) (* trailing \r\n consumed! *)
+        in
+        let body =
+            (* TODO fallback on size defined in Transfer-Encoding if
+              Content-Length isn't defined *)
+          if meth = `POST then
+            Buffer.contents
+              (try  (* read only Content-Length bytes *)
+                let limit_raw =
+                  (try
+                    List.assoc "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 ok? *)
+            ""
+        in
+        (headers, body))
   in
   let query_post_params =
     match meth with
@@ -110,46 +118,11 @@ class request ic =
     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
-
-    method meth = meth
-    method uri = uri
-    method path = path
-    method param name =
-      try
-        Hashtbl.find params_tbl name
-      with Not_found ->
-        raise (Param_not_found name)
-    method paramAll name = List.rev (Hashtbl.find_all params_tbl name)
-    method params = params
-
-    method private fstLineToString =
-      sprintf
-        "%s %s %s"
-        (string_of_method self#meth)
-        self#uri
-        (string_of_version self#version)
+      let method_string = string_of_method self#meth in
+      match self#version with
+      | Some version ->
+          sprintf "%s %s %s" method_string self#uri (string_of_version version)
+      | None -> sprintf "%s %s" method_string self#uri
 
   end
-*)
 
index 913c227551acd60a960cb42a5c60ee428ec8ff3b..6fc3213254114f63a76a30ca47ec236b327b42a3 100644 (file)
@@ -47,8 +47,10 @@ class response
     (* "version code reason_phrase" *)
   object (self)
 
+      (* note that response objects can't be created with a None version *)
     inherit
-      Http_message.message ~body ~headers ~version ~clisockaddr ~srvsockaddr
+      Http_message.message
+        ~body ~headers ~version:(Some version) ~clisockaddr ~srvsockaddr
 
     val mutable _code =
       match status with
@@ -56,6 +58,13 @@ class response
       | Some (s: Http_types.status) -> code_of_status s
     val mutable _reason: string option = None
 
+    method private getRealVersion =
+      match self#version with
+      | None ->
+          failwith ("Http_response.fstLineToString: " ^
+            "can't serialize an HTTP response with no HTTP version defined")
+      | Some v -> string_of_version v
+
     method code = _code
     method setCode c =
       ignore (status_of_code c);  (* sanity check on c *)
@@ -68,9 +77,8 @@ class response
       | Some r -> r
     method setReason r = _reason <- Some r
     method statusLine =
-      String.concat
-        " "
-        [string_of_version self#version; string_of_int self#code; self#reason]
+      String.concat " "
+        [self#getRealVersion; string_of_int self#code; self#reason]
     method setStatusLine s =
       try
         let subs = Pcre.extract ~rex:status_line_RE s in
@@ -104,11 +112,7 @@ class response
     method setServer s = self#replaceHeader "Server" s
 
     method private fstLineToString =
-      sprintf
-        "%s %d %s"
-        (string_of_version self#version)
-        self#code
-        self#reason
+      sprintf "%s %d %s" self#getRealVersion self#code self#reason
 
   end
 
index 909b4681adc2a74eb0214ac2a7cecfab3febde96..34c8481a7df72109d811a14bc25fdd34232e25f3 100644 (file)
@@ -128,6 +128,7 @@ exception Invalid_HTTP_method of string
 exception Invalid_code of int
 exception Invalid_status of status
 
+exception Malformed_URL of string
 exception Malformed_query of string
 exception Malformed_query_part of string * string
 exception Unsupported_method of string
@@ -146,7 +147,7 @@ exception Quit
 
 class type message = object
 
-    method version: version
+    method version: version option
     method setVersion: version -> unit
 
     method body: string