11import gleam/bit_builder
22import gleam/erlang/process
3+ import gleam/erlang/os
34import gleam/http/request . { Request }
45import gleam/http/response . { Response }
56import mist . { Connection , ResponseData }
67import gleam/httpc
7- import gleam/http . { Get , Http }
8- import gleam/string . { join }
8+ import gleam/http . { Method , Scheme }
9+ import gleam/string
10+ import gleam/io
11+ import gleam/option . { Option , unwrap }
12+ import gleam/result
13+ import gleam/int
914
10- fn handle_website ( segments : List ( String ) ) -> Response ( ResponseData ) {
15+ pub type Website {
16+ Website (
17+ target_host : String ,
18+ target_port : Int ,
19+ scheme : Scheme ,
20+ method : Method ,
21+ path : String ,
22+ )
23+ }
24+
25+ fn handle_website ( config : Website ) -> Response ( ResponseData ) {
1126 let result =
1227 request . new ( )
13- |> request . set_scheme ( Http )
14- |> request . set_method ( Get )
15- |> request . set_host ( "localhost" )
16- |> request . set_port ( 1234 )
17- |> request . set_path ( join ( segments , "/" ) )
28+ |> request . set_scheme ( config . scheme )
29+ |> request . set_method ( config . method )
30+ |> request . set_host ( config . target_host )
31+ |> request . set_port ( config . target_port )
32+ |> request . set_path ( config . path )
1833 |> httpc . send
1934
2035 case result {
@@ -27,15 +42,97 @@ fn handle_website(segments: List(String)) -> Response(ResponseData) {
2742 }
2843}
2944
45+ type Image {
46+ Image (
47+ base_url : String ,
48+ api_token : String ,
49+ path : List ( String ) ,
50+ query : Option ( String ) ,
51+ )
52+ }
53+
54+ fn handle_images ( config : Image ) -> Response ( ResponseData ) {
55+ let url =
56+ "/api/cockpit/image?token=" <> config . api_token <> "&src=" <> config . base_url <> "/storage/uploads/" <> string . join (
57+ config . path ,
58+ "/" ,
59+ ) <> "&" <> unwrap ( config . query , "" )
60+
61+ let result =
62+ request . new ( )
63+ |> request . set_host ( string . replace ( config . base_url , "https://" , "" ) )
64+ |> request . set_path ( url )
65+ |> request . set_body ( << >> )
66+ |> httpc . send_bits
67+
68+ case result {
69+ Ok ( r ) ->
70+ response . new ( 200 )
71+ |> response . set_body ( mist . Bytes ( bit_builder . from_bit_string ( r . body ) ) )
72+ Error ( _ ) ->
73+ response . new ( 404 )
74+ |> response . set_body ( mist . Bytes ( bit_builder . from_string ( "<h1>nope</h1>" ) ) )
75+ }
76+ }
77+
78+ type Configuration {
79+ Configuration (
80+ base_url : String ,
81+ api_token : String ,
82+ target_host : String ,
83+ target_port : Int ,
84+ port : Int ,
85+ )
86+ }
87+
88+ fn load_configuration ( ) -> Result ( Configuration , String ) {
89+ case
90+ result . all ( [
91+ os . get_env ( "COCKPIT_BASE_URL" ) ,
92+ os . get_env ( "COCKPIT_API_TOKEN" ) ,
93+ os . get_env ( "TARGET_HOST" ) ,
94+ os . get_env ( "TARGET_PORT" ) ,
95+ os . get_env ( "PORT" ) ,
96+ ] )
97+ {
98+ Ok ( [ base_url , api_token , target_host , target_p , p ] ) ->
99+ case result . all ( [ int . parse ( target_p ) , int . parse ( p ) ] ) {
100+ Ok ( [ target_port , port ] ) ->
101+ Ok ( Configuration ( base_url , api_token , target_host , target_port , port ) )
102+ Error ( _ ) -> Error ( "Port values are not numbers" )
103+ }
104+ Error ( _ ) -> Error ( "Missing environment variables" )
105+ }
106+ }
107+
30108pub fn main ( ) {
31- fn ( req : Request ( Connection ) ) -> Response ( ResponseData ) {
32- case request . path_segments ( req ) {
33- _ as segments -> handle_website ( segments )
109+ case load_configuration ( ) {
110+ Ok ( config ) -> {
111+ fn ( req : Request ( Connection ) ) -> Response ( ResponseData ) {
112+ case request . path_segments ( req ) {
113+ [ "image" , "api" , .. path ] ->
114+ handle_images ( Image (
115+ config . base_url ,
116+ config . api_token ,
117+ path ,
118+ req . query ,
119+ ) )
120+ _ ->
121+ handle_website ( Website (
122+ config . target_host ,
123+ config . target_port ,
124+ req . scheme ,
125+ req . method ,
126+ req . path ,
127+ ) )
128+ }
129+ }
130+ |> mist . new
131+ |> mist . port ( config . port )
132+ |> mist . start_http
133+
134+ process . sleep_forever ( )
34135 }
136+ Error ( message ) -> io . print_error ( message )
35137 }
36- |> mist . new
37- |> mist . port ( 8000 )
38- |> mist . start_http
39-
40- process . sleep_forever ( )
41138}
0 commit comments