0

I'm looking for a way to implement a proxy strategy for local web development integrating to other apps and services. The app I'm trying to develop integrates with several other apps on the same site (e.g. https://example.com/myapp /login, /app2).

CHALLENGES

Here are some of the challenges:

  • It is very difficult to stand up the other apps in a local context because of their dependencies/proprietary systems. It is easier to point integrations at actual deployed environments (e.g. stage).

  • Outbound integrations can be configured, but inbound integrations break. For example, if a user is not logged in local/myapp, then we redirect to stage/login (another app in the target integration) which logs a user in and redirects back to stage/myapp, but on the wrong domain. Furthermore, the login cookie is written to the wrong domain context (stage, not local).

  • Designing stage/login so that it can return to arbitrary locations using a return param, like url=local/myapp is a security risk.

  • SSL is provided by another layer, meaning that local development is not configured for SSL, but local to stage integration would require switching contexts: http://local/myapp -> https://stage/login -> http://local/myapp.

EXPERIMENTS

My local development copy runs on http://myworkstation.dhcp.example.com:3000/myapp.

What I would like is the ability to setup a proxy such that traffic going to:

  • https://example.com/myapp/* -> http://myworkstation.dhcp.example.com:3000/myapp/*
  • everything else goes to the originally requested url https://example.com/* -> https://example.com/*

The effect I would like to achieve is like Charles Proxy's map remote feature, allowing a locally served site to 'overlay' a remote site.

I've read about various Apache modules mod_proxy, mod_rewrite and basically want a forwarding proxy for everything except a chosen subdirectory (maybe rewrite? maybe reverse proxy?). I've also looked at Squid.

I've tried several combinations, but I'm lacking the general approach for doing this. Is something like this possible using Apache mod_proxy and/or mod_rewrite?

For some context, here's my attempt so far, but I can only get the forward proxy to work. I'm using Firefox and setting the proxy for all protocols to myworkstation.dhcp.example.com:8118

Listen 8118

<VirtualHost *:8118>

# Enable forward proxy
ProxyRequests On

# Add "Via" header
ProxyVia On

<Proxy *>
  Order deny,allow
  Deny from all
  Allow from example.com  # local devs only!
</Proxy> 


# local Rails app, e.g. $ rails s -e stage
# local request:  http://myworkstation.dhcp.example.com:3000/myapp
# normal stage requests:  https://stage.example.com/myapp
# app logs in via another app: https://stage.example.com/login
# which I want to delegate to without standing up another local app.

# which to use? hmmm...
#ProxyRemote "https://stage.example.com/myapp/" "http://myworkstation.dhcp.example.com:3000/myapp/"
#ProxyPass /myapp http://myworkstation.dhcp.example.com:3000/myapp
#ProxyPassReverse /myapp/ http://myworkstation.dhcp.example.com:3000/myapp/

#RewriteEngine on
#RewriteBase "/myapp/"
#RewriteRule "^/myapp/(.*)$" "http://myworkstation.dhcp.example.com:3000/myapp/$1" [P]
#ProxyPassReverse "/myapp/" "http://myworkstation.dhcp.example.com:3000/myapp/"

# another approach, maybe via Passenger?


ServerName integration-proxy

ErrorLog "/var/log/apache2/integration-proxy-error.log"

</VirtualHost>
2
  • Wouldn't it be easier to have the integration points as configuration entries, so you could change the URL easily? Simple is often best. Messing with the web server is overly complex.
    – Tim
    May 2, 2017 at 23:18
  • Please edit your question to add appropriate background, ie your two comments. A single cohesive piece of text is easier to understand and answer than when information is fragmented into comments. Once that's done you can delete your comments.
    – Tim
    May 3, 2017 at 18:54

1 Answer 1

0

I solved this a while ago, but never posted the solution. Here's one way of doing it:

Given:

First, add the following in /etc/apache2/sites-available/mysite.conf to your <VirtualHost *:80> block:

  PassengerFriendlyErrorPages on
  IncludeOptional /etc/apache2/apps/*.conf
  ProxyPass / http://test.example.com/
  ProxyPassReverse / http://test.example.com/

Next, in your /etc/apache2/apps/myapp.conf: ProxyPass /myapp !

<Location /myapp>
    PassengerRuby /local/rvm/gems/ruby-2.3.5@myapp/wrappers/ruby
    PassengerAppRoot /local/myapp
    PassengerAppEnv development
    PassengerBaseURI /myapp
    SetEnv RAILS_RELATIVE_URL_ROOT /myapp
</Location>

Alias /myapp /local/myapp/public
<Directory /local/myapp/public>
    Allow from all
    Options -MultiViews
    # Uncomment this if you're on Apache >= 2.4:
    Require all granted
</Directory>

This configuration will allow your local Rails app to serve any content from its suburi (i.e. http://localhost/myapp) and any content from your integration site as well.

For example, say your integration site has images at http://test.example.com/images/*. These will be available at http://localhost/images as well, so if you use absolute relative image tags in your rails app like the following, they will work:

  <img src="/images/wave.jpg">

Hope this helps other devs with similar integration test scenarios!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .