Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions src/extensions/accesscontrol.ml
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,19 @@ let ip s =
in
fun ri ->
let r =
match Ocsigen_request.remote_ip_parsed ri with
| `Ip ip -> Ipaddr.Prefix.mem ip prefix
| `Unix _ -> false
match Ocsigen_request.client_conn ri with
| `Inet (ip, _) -> Ipaddr.Prefix.mem ip prefix
| _ -> false
in
if r
then
Logs.info ~src:section (fun fmt ->
fmt "IP: %s matches %s" (Ocsigen_request.remote_ip ri) s)
fmt "IP: %s matches %s" (Ocsigen_request.client_conn_to_string ri) s)
else
Logs.info ~src:section (fun fmt ->
fmt "IP: %s does not match %s" (Ocsigen_request.remote_ip ri) s);
fmt "IP: %s does not match %s"
(Ocsigen_request.client_conn_to_string ri)
s);
r

let port port ri =
Expand Down Expand Up @@ -222,22 +224,22 @@ let allow_forward_for_handler ?(check_equal_ip = false) () =
let last_proxy = List.last proxies in
let proxy_ip = Ipaddr.of_string_exn last_proxy in
let equal_ip =
match Ocsigen_request.remote_ip_parsed request_info with
| `Ip r_ip -> Ipaddr.compare proxy_ip r_ip = 0
| `Unix _ -> false
match Ocsigen_request.client_conn request_info with
| `Inet (r_ip, _) -> Ipaddr.compare proxy_ip r_ip = 0
| _ -> false
in
if equal_ip || not check_equal_ip
then
{ request with
Ocsigen_extensions.request_info =
Ocsigen_request.update ~forward_ip:proxies
~remote_ip:original_ip request_info }
~client_conn:(`Forwarded_for original_ip) request_info }
else (
(* the announced ip of the proxy is not its real ip *)
Logs.warn ~src:section (fun fmt ->
fmt
"X-Forwarded-For: host ip (%s) does not match the header (%s)"
(Ocsigen_request.remote_ip request_info)
(Ocsigen_request.client_conn_to_string request_info)
header);
request)
| _ ->
Expand Down
2 changes: 1 addition & 1 deletion src/extensions/revproxy.ml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ let gen dir = function
(Ocsigen_request.address request_info)
in
String.concat ", "
(Ocsigen_request.remote_ip request_info
(Ocsigen_request.client_conn_to_string request_info
:: Ocsigen_request.forward_ip request_info
@ [address])
in
Expand Down
18 changes: 8 additions & 10 deletions src/server/ocsigen_cohttp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,13 @@ end
let handler ~ssl ~address ~port ~connector (flow, conn) request body =
let filenames = ref [] in
let edn = Conduit_lwt_unix.endp_of_flow flow in
let rec getsockname = function
| `TCP (ip, port) -> Unix.ADDR_INET (Ipaddr_unix.to_inet_addr ip, port)
| `Unix_domain_socket path -> Unix.ADDR_UNIX path
| `TLS (_, edn) -> getsockname edn
| `Unknown err -> raise (Failure ("resolution failed: " ^ err))
| `Vchan_direct _ -> raise (Failure "VChan not supported")
| `Vchan_domain_socket _ -> raise (Failure "VChan not supported")
let client_conn =
match edn with
| `TCP (ip, port) | `TLS (_, `TCP (ip, port)) -> `Inet (ip, port)
| `Unix_domain_socket path | `TLS (_, `Unix_domain_socket path) ->
`Unix path
| _ -> `Unknown
in
let sockaddr = getsockname edn in
let connection_closed =
try fst (Hashtbl.find connections conn)
with Not_found ->
Expand Down Expand Up @@ -110,7 +108,7 @@ let handler ~ssl ~address ~port ~connector (flow, conn) request body =
in
(* TODO: equivalent of Ocsigen_range *)
let request =
Ocsigen_request.make ~address ~port ~ssl ~filenames ~sockaddr ~body
Ocsigen_request.make ~address ~port ~ssl ~filenames ~client_conn ~body
~connection_closed request
in
Lwt.finalize
Expand All @@ -120,7 +118,7 @@ let handler ~ssl ~address ~port ~connector (flow, conn) request body =
(match Ocsigen_request.host request with
| None -> "<host not specified in the request>"
| Some h -> h)
(Ocsigen_request.remote_ip request)
(Ocsigen_request.client_conn_to_string request)
(Option.value ~default:""
(Ocsigen_request.header request Ocsigen_header.Name.user_agent))
(Option.fold ~none:""
Expand Down
55 changes: 23 additions & 32 deletions src/server/ocsigen_request.ml
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,18 @@ let make_uri u =
and u_get_params_flat = lazy (flatten_get_params (Lazy.force u_get_params)) in
{u_uri; u_get_params; u_get_params_flat; u_path; u_path_string}

type client_conn =
[ `Inet of Ipaddr.t * int
| `Unix of string
| `Forwarded_for of string
| `Unknown ]

type t =
{ r_address : Ocsigen_config.Socket_type.t
; r_port : int
; r_ssl : bool
; r_filenames : string list ref
; r_sockaddr : Lwt_unix.sockaddr
; r_remote_ip : string Lazy.t
; r_remote_ip_parsed : [`Ip of Ipaddr.t | `Unix of string] Lazy.t
; r_client_conn : client_conn
; r_forward_ip : string list
; r_uri : uri
; r_meth : Cohttp.Code.meth
Expand All @@ -81,31 +85,16 @@ let make
~port
~ssl
~filenames
~sockaddr
~client_conn
~body
~connection_closed
request
=
let r_remote_ip =
lazy
(match sockaddr with
| Unix.ADDR_INET (ip, _port) -> Unix.string_of_inet_addr ip
| ADDR_UNIX f -> f)
in
let r_remote_ip_parsed =
lazy
(match sockaddr with
| Unix.ADDR_INET (ip, _port) ->
`Ip (Ipaddr.of_string_exn (Unix.string_of_inet_addr ip))
| ADDR_UNIX f -> `Unix f)
in
{ r_address = address
; r_port = port
; r_ssl = ssl
; r_filenames = filenames
; r_sockaddr = sockaddr
; r_remote_ip
; r_remote_ip_parsed
; r_client_conn = client_conn
; r_forward_ip = forward_ip
; r_uri = make_uri (Cohttp.Request.uri request)
; r_encoding = Cohttp.Request.encoding request
Expand All @@ -127,7 +116,7 @@ let path {r_uri = {u_path; _}; _} = Lazy.force u_path
let update
?ssl
?forward_ip
?remote_ip
?client_conn
?sub_path
?meth
?get_params_flat
Expand All @@ -139,8 +128,7 @@ let update
; r_uri = {u_uri; _} as r_uri
; r_meth
; r_forward_ip
; r_remote_ip
; r_remote_ip_parsed
; r_client_conn
; r_cookies_override
; r_body
; r_sub_path
Expand All @@ -150,11 +138,8 @@ let update
let r_ssl = match ssl with Some ssl -> ssl | None -> r_ssl
and r_forward_ip =
match forward_ip with Some forward_ip -> forward_ip | None -> r_forward_ip
and r_remote_ip, r_remote_ip_parsed =
match remote_ip with
| Some remote_ip ->
lazy remote_ip, lazy (`Ip (Ipaddr.of_string_exn remote_ip))
| None -> r_remote_ip, r_remote_ip_parsed
and r_client_conn =
match client_conn with Some c -> c | None -> r_client_conn
and r_sub_path = match sub_path with Some _ -> sub_path | None -> r_sub_path
and r_body =
match post_data with
Expand Down Expand Up @@ -192,8 +177,7 @@ let update
; r_uri
; r_meth
; r_forward_ip
; r_remote_ip
; r_remote_ip_parsed
; r_client_conn
; r_body
; r_cookies_override
; r_sub_path
Expand Down Expand Up @@ -292,8 +276,15 @@ let post_params r s i =
let files r s i =
match force_post_data r s i with Some v -> Some (v >|= snd) | None -> None

let remote_ip {r_remote_ip; _} = Lazy.force r_remote_ip
let remote_ip_parsed {r_remote_ip_parsed; _} = Lazy.force r_remote_ip_parsed
let client_conn {r_client_conn = c; _} = c

let client_conn_to_string {r_client_conn = c; _} =
match c with
| `Inet (ip, _) -> Ipaddr.to_string ip
| `Unix path -> "unix:" ^ path
| `Forwarded_for ip -> "forwarded:" ^ ip
| `Unknown -> "unknown"

let forward_ip {r_forward_ip; _} = r_forward_ip
let request_cache {r_request_cache; _} = r_request_cache
let tries {r_tries; _} = r_tries
Expand Down
22 changes: 18 additions & 4 deletions src/server/ocsigen_request.mli
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ type file_info = Ocsigen_multipart.file_info =

type post_data = (string * string) list * (string * file_info) list

type client_conn =
[ `Inet of Ipaddr.t * int
| `Unix of string
| `Forwarded_for of string
| `Unknown ]
(** Type of connection used by the client. [`Inet] means the client connected
through the Internet. [`Forwarded_for] means that the client connected
through a proxy and carries the IP address reported in the HTTP headers. *)

val make :
?forward_ip:string list
-> ?sub_path:string
Expand All @@ -19,7 +28,7 @@ val make :
-> port:int
-> ssl:bool
-> filenames:string list ref
-> sockaddr:Lwt_unix.sockaddr
-> client_conn:client_conn
-> body:Cohttp_lwt.Body.t
-> connection_closed:unit Lwt.t
-> Cohttp.Request.t
Expand All @@ -28,7 +37,7 @@ val make :
val update :
?ssl:bool
-> ?forward_ip:string list
-> ?remote_ip:string
-> ?client_conn:client_conn
-> ?sub_path:string
-> ?meth:Cohttp.Code.meth
-> ?get_params_flat:(string * string) list
Expand Down Expand Up @@ -74,8 +83,13 @@ val post_params :
-> Int64.t option
-> (string * string) list Lwt.t option

val remote_ip : t -> string
val remote_ip_parsed : t -> [`Ip of Ipaddr.t | `Unix of string]
val client_conn : t -> client_conn
(** The way the client connects to the server (for example, its IP address if
connected over the internet). *)

val client_conn_to_string : t -> string
(** A textual representation of [client_conn] suitable for use in logs. *)

val forward_ip : t -> string list
val content_type : t -> content_type option
val request_cache : t -> Polytables.t
Expand Down
4 changes: 2 additions & 2 deletions test/extensions/deflatemod.t/run.t
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
$ source ../../server-test-helpers.sh
$ run_server ./test.exe
ocsigen:main: [WARNING] Command pipe created
ocsigen:access: connection for local-test from (): /index.html
ocsigen:access: connection for local-test from unix: (): /index.html
ocsigen:ext: [INFO] host found! local-test:0 matches .*
ocsigen:ext:staticmod: [INFO] Is it a static file?
ocsigen:local-file: [INFO] Testing "./index.html".
ocsigen:local-file: [INFO] checking if file index.html can be sent
ocsigen:ext: [INFO] Compiling exclusion regexp $^
ocsigen:local-file: [INFO] Returning "./index.html".
ocsigen:access: connection for local-test from (): /index.html
ocsigen:access: connection for local-test from unix: (): /index.html
ocsigen:ext: [INFO] host found! local-test:0 matches .*
ocsigen:ext:staticmod: [INFO] Is it a static file?
ocsigen:local-file: [INFO] Testing "./index.html".
Expand Down