For the past few months I have been working on migrating our customer’s applications to Amazon cloud. As part of the migration I was making some environmental changes like switching to light weight web servers. Specifically for Rails applications I moved them from Lighttpd to using mongrel clusters (mongrel_cluster) front-ended by Nginx web server. One of the application had a web and a web service component. The web service component is being used by both the web application as well as by desktop client applications from the internet. I wanted the access from web application to web services go through internal connection than the public URL used by the desktop client application. What I did was configure two virtual hosts in Ngnix, one with the subdomain running on port 80 which will be used by the client applications on the internet and the other virtual host on localhost and a port (8880). Both of these virtual hosts pass the requests through proxy_pass to the mongrel cluster.
The connection from the client applications to the web service worked fine, but the connection from the web application to the web service failed. Inspecting the log file showed the below error.
streamHandler.rb in `send_post’: 301: Moved Permanently (SOAP::HTTPStreamError)
I was originally thinking that this could be a problem with using the web services application behind NGINX and proxying the request. But if that were the case, then even the requests coming from the client applications through the subdomain URL should have failed. So I wanted to dig this inside.
Oh by the way before I proceed, the application was on rails 1.1.6, rubygem 0.9.0 and ruby 1.8.5. I know this combination is quite old, but we never got a chance to port the app to newer versions and without code changes it breaks in the newer versions of ruby/rails.
So, I opened irb and tried to use the SOAP libraries directly to make a request to the web services. Here is the code snippet.
As you can see in the irb output above, once I create a RPC connection to the web services providing the WSDL URL, you can see the URL to the web service API misses the port number! Apparently the service calls are routed to my default redirection configuration in the NGINX server to the web application. Looking at the log in the NGINX web server confirms that the request is redirected with HTTP 301 status, which is what is thrown up as above.
Honestly I don’t know what would be the fix at a code level, but I did solve this problem, by simply changing the virtual host for localhost:8880 to localhost:80. My reasoning here is since I have specific server domain configurations listening to port 80 and one would not be able to access the localhost:80 from the internet.
My question now and something that I have to dig is, is there a way to tell the soap api explicitly, always use the host and port when calling the web services. Please post any comments/answers if you are aware of. Thanks.