Added experimental proxy route to backend api - fixes #91

Change-Id: I9a055b33c8cacef6cfa564467a17e7f55a1eeef5
diff --git a/lib/Kalamar.pm b/lib/Kalamar.pm
index 7856e91..c9e9374 100644
--- a/lib/Kalamar.pm
+++ b/lib/Kalamar.pm
@@ -8,7 +8,7 @@
 use List::Util 'none';
 
 # Minor version - may be patched from package.json
-our $VERSION = '0.34';
+our $VERSION = '0.35';
 
 # Supported version of Backend API
 our $API_VERSION = '1.0';
@@ -58,9 +58,29 @@
 
   $self->log->info('Mode is ' . $self->mode);
 
-  # Specific path prefixing
+  # Get configuration
   my $conf = $self->config('Kalamar');
-  if ($conf && $conf->{proxy_prefix}) {
+  unless ($conf) {
+    $self->config(Kalamar => {});
+    $conf = $self->config('Kalamar');
+  };
+
+  # Check for API endpoint and set the endpoint accordingly
+  if ($conf->{api}) {
+
+    # The api endpoint should be defined as a separated path
+    # and version string
+    $self->log->warn(
+      'Kalamar.api is no longer supported in configurations '.
+        'in favor of Kalamar.api_path'
+      );
+  };
+
+  unless ($conf->{api_path} || $ENV{KALAMAR_API}) {
+    $self->log->warn('Kalamar-api_path not defined in configuration');
+  };
+
+  if ($conf->{proxy_prefix}) {
 
     for ($self->sessions) {
       $_->cookie_path($conf->{proxy_prefix});
@@ -78,28 +98,9 @@
       });
   };
 
-  # Check for API endpoint and set the endpoint accordingly
-  if ($conf->{api}) {
-
-    # The api endpoint should be defined as a separated path
-    # and version string
-    $self->log->info(
-      'Kalamar.api is deprecated in configurations '.
-        'in favor of Kalamar.api_path'
-      );
-  }
-
-  # Set from environment variable
-  elsif ($ENV{'KALAMAR_API'}) {
-    $conf->{api} = $ENV{'KALAMAR_API'};
-  }
-
   # API is not yet set - define
-  else {
-
-    $conf->{api} =
-      Mojo::URL->new($conf->{api_path})->path('v' . ($conf->{api_version} // $API_VERSION) . '/')->to_string;
-  };
+  $conf->{api_path} //= $ENV{KALAMAR_API};
+  $conf->{api_version} //= $API_VERSION;
 
   # Add development path
   if ($self->mode eq 'development') {
@@ -211,7 +212,7 @@
 
   $self->config(navi => $navi);
 
-  $self->log->info('API expected at ' . $self->config->{Kalamar}->{api});
+  $self->log->info('API expected at ' . $self->korap->api);
 
   # Establish routes with authentification
   my $r = $self->routes;
@@ -234,6 +235,10 @@
   $r->get('/contact')->to('documentation#contact');
   $r->get('/contact')->mail_to_chiffre('documentation#contact');
 
+  # API proxy route
+  # $r->any('/api/v#apiv' => [apiv => ['1.0']])->to('Proxy#pass');
+  # $r->any('/api/v#apiv/*path' => [apiv => ['1.0']])->to('Proxy#pass');
+
   # Match route
   # Corpus route
   my $corpus = $r->get('/corpus')->to('search#corpus_info')->name('corpus');
@@ -266,7 +271,7 @@
 
 =head2 COPYRIGHT AND LICENSE
 
-Copyright (C) 2015-2018, L<IDS Mannheim|http://www.ids-mannheim.de/>
+Copyright (C) 2015-2019, L<IDS Mannheim|http://www.ids-mannheim.de/>
 Author: L<Nils Diewald|http://nils-diewald.de/>
 
 Kalamar is developed as part of the L<KorAP|http://korap.ids-mannheim.de/>
diff --git a/lib/Kalamar/Controller/Proxy.pm b/lib/Kalamar/Controller/Proxy.pm
new file mode 100644
index 0000000..ed9acef
--- /dev/null
+++ b/lib/Kalamar/Controller/Proxy.pm
@@ -0,0 +1,53 @@
+package Kalamar::Controller::Proxy;
+use Mojo::Base 'Mojolicious::Controller';
+
+# Pass proxy command to API
+sub pass {
+  my $c = shift;
+
+  my $apiv = $c->stash('apiv');
+  my $path = $c->stash('path') // '';
+
+  # Get the original request
+  my $req = $c->req;
+
+  # Clone and clean request headers
+  my $headers = $req->headers->clone->dehop;
+
+  # Set Proxy information
+  $headers->header('X-Proxy' => 'Kalamar');
+
+  # Set clean X-Forwarded-For header
+  $headers->header(
+    'X-Forwarded-For' => $c->client_ip
+  );
+
+  # Get parameters of the request
+  my $params = $req->query_params->clone;
+  my $api_url;
+
+  # Get API request for proxying
+  my $url = Mojo::URL->new($c->korap->api($apiv))->path($path)->query($params);
+
+  # Resend headers
+  my $tx = $c->kalamar_ua->build_tx(
+    $req->method => $url => $headers->to_hash => $req->body
+  );
+
+  # Pipe through system (which means
+  # an authorization header may be set)
+  $c->app->plugins->emit_hook(
+    before_korap_request => ($c, $tx)
+  );
+
+  # return $c->render(text => 'okay ' . $url);
+
+  $c->proxy->start_p($tx)->wait;
+  # $tx->res->content->once(
+  #   body => sub {
+  #     $c->res->headers->header('X-Proxy' => 'Kalamar');
+  #   }
+  # );
+};
+
+1;
diff --git a/lib/Kalamar/Plugin/KalamarHelpers.pm b/lib/Kalamar/Plugin/KalamarHelpers.pm
index a85f2ae..f97f453 100644
--- a/lib/Kalamar/Plugin/KalamarHelpers.pm
+++ b/lib/Kalamar/Plugin/KalamarHelpers.pm
@@ -13,6 +13,14 @@
 sub register {
   my ($plugin, $mojo) = @_;
 
+  # Get config
+  my $conf = $mojo->config('Kalamar');
+
+  # Define API_URL
+  my $api_url = Mojo::URL->new(
+    $conf->{api_path} // '-'
+  )->path('v' . ($conf->{api_version} // '-') . '/')->to_string;
+
   # Embed the korap architecture image
   $mojo->helper(
     korap_overview => sub {
@@ -290,7 +298,19 @@
   # Get the KorAP API endpoint
   $mojo->helper(
     'korap.api' => sub {
-      return shift->config('Kalamar')->{api};
+      my $c = shift;
+
+      # TODO:
+      #   May clone a Mojo::URL object instead
+      return $api_url unless @_;
+
+      my $apiv = shift;
+      if (!$apiv || $apiv eq $conf->{api_version}) {
+        return $api_url;
+      };
+
+      # Return newly created API URL
+      return Mojo::URL->new($conf->{api_path})->path('v' . $apiv . '/')->to_string;
     }
   );
 
diff --git a/lib/Kalamar/Plugin/KalamarUser.pm b/lib/Kalamar/Plugin/KalamarUser.pm
index 60fadfe..cbbcda0 100644
--- a/lib/Kalamar/Plugin/KalamarUser.pm
+++ b/lib/Kalamar/Plugin/KalamarUser.pm
@@ -11,6 +11,9 @@
 #   This Plugin will be removed in favour of
 #   Kalamar::Plugin::Auth!
 
+# TODO:
+#   Replace plugin-api with korap->api!
+
 sub register {
   my ($plugin, $mojo, $param) = @_;