javascript - How do I use a php authentication script as proxy to CouchDB and still maintain full REST API functionality? -


i've installed couchdb version 1.2.1 , test can access using following apache rewrite in centos 6:

rewriterule couchdb/(.*)$ http://127.0.0.1:5984/$1 [qsa,p] 

i have php authentication class use across home grown api support mobile apps. api accepts , authenticates each request using hmac signature included in url so:

https://api.domain.com/endpoint/?timestamp=[timestamp]&signature=[signature]&id=[id]...etc 

each endpoint has corresponding script ensures checks proper signature before processing.

ideally, i'd replace above reverse proxy rewrite rule sort of php script act gatekeeper/gateway couchdb instance, leveraging authentication class, while still preserving native couchdb rest api functionality, including not limited replication , cookie authentication users (the above api authentication). can done? i've tried using this solution modified below, while in fact kick valid json responses, replication fails, , suspect other aspects such user authentication well:

<?php require_once('couchdbproxy.php'); require_once("common.php");  //set vars $resource = $_get['resource']; $id = $_get['appid']; $timestamp = $_get['timestamp']; $signature = $_get['signature'];  //use common class validating sig if ( access::validsignature( $id, $timestamp, $signature ) ) {     $proxy = new couchdbproxy('127.0.0.1', '5984');     $proxy->proxy('/'.$resource); } ?>   <?php //couchdb_proxy.php      class couchdbproxy     {         public $host;         public $port;         public $timeout = 10;          /**          * initialize proxy service          *          * @param string $host host requests should forwarded          * @param string $port port on host use          * @author adam venturella          */         public function __construct($host, $port)         {             $this->host            = $host;             $this->port            = $port;         }          /**          * begin proxying          *          * @return void          * @author adam venturella          */          public function proxy($resource)         {             $verb    = strtolower($_server['request_method']);             $command = null;              switch($verb)             {                 case 'get':                     $command = $this->proxy_get($resource);                     break;                  case 'post':                     $command = $this->proxy_post($resource);                     break;                  case 'put':                     $command = $this->proxy_put($resource);                     break;                  case 'delete':                     $command = $this->proxy_delete($resource);                     break;                  case 'head':                     $command = $this->proxy_head($resource);                     break;             }              if($command)             {                 curl_exec($command);                 curl_close($command);             }         }          /**          * handle requests          *          * @return void          * @author adam venturella          */         private function proxy_get($resource)         {             return $this->request($resource);         }          /**          * handle head requests          *          * @return void          * @author adam venturella          */         private function proxy_head($resource)         {             $command = $this->request($resource);             curl_setopt( $command, curlopt_nobody, true);             return $command;         }          /**          * handle post requests          *          * @return void          * @author adam venturella          */         private function proxy_post($resource)         {             $command = $this->request($resource);             $data    = file_get_contents("php://input");             curl_setopt($command, curlopt_post, true);             curl_setopt($command, curlopt_postfields, $data);              return $command;         }          /**          * handle delete requests          *          * @return void          * @author adam venturella          */         private function proxy_delete($resource)         {             $command = $this->request($resource);             curl_setopt($command, curlopt_customrequest, 'delete');               return $command;         }          /**          * handle put requests          *          * @return void          * @author adam venturella          */         private function proxy_put($resource)         {             $command = $this->request($resource);              $data     = file_get_contents("php://input");             curl_setopt($command, curlopt_customrequest, 'put');               curl_setopt($command, curlopt_postfields, $data);              return $command;         }          /**          * build basic request          *          * @return void          * @author adam venturella          */         private function request($resource)         {             $action    = $_server['request_method'];             $uri       = $resource;     //      $uri       = $_server['request_uri'];              $params    = null;              //added http://stackoverflow.com/questions/2916232/call-to-undefined-function-apache-request-headers             if( !function_exists('apache_request_headers') ) {                 function apache_request_headers() {                   $arh = array();                   $rx_http = '/\ahttp_/';                   foreach($_server $key => $val) {                     if( preg_match($rx_http, $key) ) {                       $arh_key = preg_replace($rx_http, '', $key);                       $rx_matches = array();                       // nasty string manipulations restore original letter case                       // should work in cases                       $rx_matches = explode('_', $arh_key);                       if( count($rx_matches) > 0 , strlen($arh_key) > 2 ) {                         foreach($rx_matches $ak_key => $ak_val) $rx_matches[$ak_key] = ucfirst($ak_val);                         $arh_key = implode('-', $rx_matches);                       }                       $arh[$arh_key] = $val;                     }                   }                   return( $arh );                 }             }             $headers   = apache_request_headers();             $context   = array();              $context[] = 'host: '.$this->host.':'.$this->port;             $context[] = 'x-forwarded-for: '.$_server['remote_addr'];             $context[] = 'x-forwarded-host: '.$_server['http_host'];             $context[] = 'x-forwarded-server: '.$_server['server_name'];              foreach($headers $key=>$value)             {                 if(strtolower($key) != 'host')                 {                     $context[] = $key.': '.$value;                 }             }              $command = curl_init();             curl_setopt( $command, curlopt_httpheader, $context);             curl_setopt( $command, curlopt_url, "http://".$this->host.':'.$this->port.$uri);             curl_setopt( $command, curlopt_binarytransfer, true );             curl_setopt( $command, curlopt_timeout, $this->timeout );             curl_setopt( $command, curlopt_headerfunction, array($this,'processresponseheaders'));             curl_setopt( $command, curlopt_writefunction, array($this,'processresponsebody'));             return $command;         }          /**          * process response body          *          * @param curl $command reference curl command used generate response          * @param string $data response body          * @return void          * @author adam venturella          */         private function processresponsebody(&$command, $data)         {             $bytes = strlen($data);             echo $data;             return $bytes;         }          /**          * process response headers          *          * @param curl $command reference curl command used generate response          * @param string $header current header in response          * @return void          * @author adam venturella          */         private function processresponseheaders(&$command, $header)         {             $bytes = strlen($header);              // curl handles chunked decoding us, response              // proxy never chunked              if ($header !== "\r\n" && strpos($header, 'chunked') === false)             {                 header(rtrim($header));             }              return $bytes;         }     }     ?> 

i've been @ days , can't seem make work i'm tossing out either getting php proxy script right, or identifying alternative approach.

i guess replication (like _changes feed, example) uses long-lived requests chunked transfer-encoding, , php proxy doesn't support well.


Comments

Popular posts from this blog

java - Jmockit String final length method mocking Issue -

asp.net - Razor Page Hosted on IIS 6 Fails Every Morning -

c++ - wxwidget compiling on windows command prompt -