You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by er...@apache.org on 2010/11/19 08:17:56 UTC

svn commit: r1036750 [2/2] - in /trafficserver/plugins/mysql_remap: ./ lib/ schema/

Added: trafficserver/plugins/mysql_remap/mysql_remap.cc
URL: http://svn.apache.org/viewvc/trafficserver/plugins/mysql_remap/mysql_remap.cc?rev=1036750&view=auto
==============================================================================
--- trafficserver/plugins/mysql_remap/mysql_remap.cc (added)
+++ trafficserver/plugins/mysql_remap/mysql_remap.cc Fri Nov 19 07:17:55 2010
@@ -0,0 +1,245 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+*/
+
+#include <ts/ts.h>
+#include <ts/remap.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "mysql/mysql.h"
+#include "lib/iniparser.h"
+#include "default.h"
+
+MYSQL mysql;
+
+typedef struct {
+  char * query;
+} my_data;
+
+bool do_mysql_remap(TSCont contp,TSHttpTxn txnp) {
+  TSMBuffer reqp;
+  TSMLoc hdr_loc, url_loc, field_loc;
+  bool ret_val = false;
+  
+  const char * request_host;
+  int request_host_length = 0;
+  const char * request_scheme;
+  int request_scheme_length = 0;
+  int request_port = 80;
+  char * query;
+  
+  MYSQL_ROW row;
+  MYSQL_RES *res;
+  
+  my_data * data = (my_data*) TSContDataGet(contp);
+  query = data->query;
+  
+  if (!TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc)) {
+    TSDebug(PLUGIN_NAME,"could not get request data");
+    return false;
+  }
+  
+  url_loc = TSHttpHdrUrlGet(reqp, hdr_loc);
+  
+  if (!url_loc) {
+    TSDebug(PLUGIN_NAME,"couldn't retrieve request url");
+    goto release_hdr;
+  }
+  
+  field_loc = TSMimeHdrFieldFind(reqp, hdr_loc, TS_MIME_FIELD_HOST, TS_MIME_LEN_HOST);
+  
+  if (!field_loc) {
+      TSDebug(PLUGIN_NAME,"couldn't retrieve request HOST header");
+      goto release_url;
+  }
+  
+  if (TSMimeHdrFieldValueStringGet (reqp, hdr_loc, field_loc, 0, &request_host, &request_host_length) != TS_SUCCESS) {
+    TSDebug(PLUGIN_NAME,"couldn't find request HOST header");
+    goto release_field;
+  }
+  
+  request_scheme = TSUrlSchemeGet(reqp,url_loc,&request_scheme_length);
+  request_port   = TSUrlPortGet(reqp,url_loc);
+
+  TSDebug(PLUGIN_NAME,"      +++++MYSQL REMAP+++++      ");
+
+  TSDebug(PLUGIN_NAME,"\nINCOMING REQUEST ->\n ::: from_scheme_desc: %.*s\n ::: from_hostname: %.*s\n ::: from_port: %d",\
+    request_scheme_length,\
+    request_scheme,\
+    request_host_length,\
+    request_host,\
+    request_port
+  );
+  
+  snprintf(query,QSIZE," \
+    SELECT \
+        t_scheme.scheme_desc, \
+        t_host.hostname, \
+        to_port \
+      FROM map \
+        INNER JOIN scheme as t_scheme ON (map.to_scheme_id = t_scheme.id) \
+        INNER JOIN scheme as f_scheme ON (map.from_scheme_id = f_scheme.id) \
+        INNER JOIN hostname as t_host ON (map.to_hostname_id = t_host.id) \
+        INNER JOIN hostname as f_host ON (map.from_hostname_id = f_host.id) \
+      WHERE \
+        is_enabled=1 \
+        AND f_host.hostname = '%.*s' \
+        AND f_scheme.id = %d \
+        AND from_port = %d \
+      LIMIT 1", \
+    request_host_length, \
+    request_host, \
+    (strcmp(request_scheme,"https") == 0) ? 2:1, \
+    request_port \
+  );
+  
+  mysql_real_query(&mysql,query,(unsigned int)strlen(query));
+  res = mysql_use_result(&mysql);
+  
+  if (!res) goto not_found; //TODO: define a fallback
+  
+  do { 
+    row = mysql_fetch_row(res);
+    if (!row) goto not_found;
+    TSDebug(PLUGIN_NAME,"\nOUTGOING REQUEST ->\n ::: to_scheme_desc: %s\n ::: to_hostname: %s\n ::: to_port: %s",row[0],row[1],row[2]);
+    TSMimeHdrFieldValueStringSet(reqp, hdr_loc, field_loc, 0,row[1],-1);
+    TSUrlHostSet(reqp,url_loc,row[1],-1);
+    TSUrlSchemeSet(reqp,url_loc,row[0],-1);
+    TSUrlPortSet(reqp,url_loc,atoi(row[2]));
+  } while(0);
+  
+  ret_val = true;
+
+not_found:
+  if (!ret_val) {
+    //lets build up a nice 404 message for someone
+    TSHttpHdrStatusSet(reqp,hdr_loc,TS_HTTP_STATUS_NOT_FOUND);
+    TSHttpTxnSetHttpRetStatus(txnp,TS_HTTP_STATUS_NOT_FOUND);
+  }
+free_stuff: 
+  if (res)
+    mysql_free_result(res);
+  if (request_host)
+    TSHandleStringRelease(reqp, hdr_loc, request_host);
+  if (request_scheme)
+    TSHandleStringRelease(reqp, hdr_loc, request_scheme);
+release_field:
+  if (field_loc)
+    TSHandleMLocRelease(reqp, hdr_loc, field_loc);
+release_url:
+  if (url_loc)
+    TSHandleMLocRelease(reqp, hdr_loc, url_loc);
+release_hdr:
+  if (hdr_loc)
+    TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc);
+  
+  return ret_val;
+}
+
+static int
+mysql_remap (TSCont contp, TSEvent event, void *edata) {
+  TSHttpTxn txnp = (TSHttpTxn) edata;
+  TSEvent reenable = TS_EVENT_HTTP_CONTINUE;
+  
+  switch(event) {
+    case TS_EVENT_HTTP_READ_REQUEST_HDR:
+      TSDebug(PLUGIN_NAME,"Reading Request");
+      TSSkipRemappingSet(txnp,1);
+      if (!do_mysql_remap(contp,txnp)) {
+        reenable = TS_EVENT_HTTP_ERROR;
+      }
+      break;
+  }
+  
+  TSHttpTxnReenable(txnp, reenable);
+  return 1;
+}
+
+void
+TSPluginInit(int argc, const char *argv[]) {
+  dictionary * ini;
+  const char * host;
+  int port;
+  const char * username;
+  const char * password;
+  const char * db;
+  
+  my_data * data = (my_data*) malloc(1*sizeof(my_data));
+  
+  TSPluginRegistrationInfo info;
+  my_bool reconnect = 1;
+  
+  info.plugin_name   = const_cast<char*>(PLUGIN_NAME);
+  info.vendor_name   = const_cast<char*>("Apache Software Foundation");
+  info.support_email = const_cast<char*>("eric@ericbalsa.com");
+
+  if (!TSPluginRegister(TS_SDK_VERSION_2_0 , &info)) {
+    TSError("mysql_remap: plugin registration failed.\n"); 
+  }
+
+  if (argc != 2) {
+    TSError( "usage: %s /path/to/sample.ini\n", argv[0] );
+    return;
+  }
+  
+  ini = iniparser_load(argv[1]);
+  if (!ini) {
+    TSError("Error with ini file (1)");
+    TSDebug(PLUGIN_NAME,"Error parsing ini file(1)");
+    return;
+  }
+  
+  host     = iniparser_getstring(ini, "mysql_remap:mysql_host", (char*)"localhost");
+  port     =    iniparser_getint(ini,"mysql_remap:mysql_port",3306);
+  username = iniparser_getstring(ini, "mysql_remap:mysql_username", NULL);
+  password = iniparser_getstring(ini, "mysql_remap:mysql_password", NULL);
+  db       = iniparser_getstring(ini, "mysql_remap:mysql_database", (char*)"mysql_remap");
+  
+  if (mysql_library_init(0, NULL, NULL)) {
+    TSError("Error initializing mysql client library");
+    TSDebug(PLUGIN_NAME,"Error initializing mysql client library");
+    return;
+  }
+  
+  if (!mysql_init(&mysql)) {
+    TSError("Could not initialize MySQL");
+    TSDebug(PLUGIN_NAME,"Could not initialize MySQL");
+    return;
+  }
+  
+  mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect);
+  
+  if (!mysql_real_connect(&mysql,host,username,password,db,port,NULL,0)) {
+    TSError("Could not connect to mysql");
+    TSDebug(PLUGIN_NAME,"Could not connect to mysql: %s",mysql_error(&mysql));
+    return;
+  }
+  
+  data->query = (char*)TSmalloc(QSIZE * sizeof(char)); //TODO: malloc smarter sizes
+      
+  TSDebug(PLUGIN_NAME, "h: %s; u: %s; p: %s; p:%d; d:%s",host,username,password,port,db);
+  TSCont cont = TSContCreate(mysql_remap, TSMutexCreate());
+  
+  TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, cont);
+
+  TSContDataSet (cont, (void *)data);
+  
+  TSDebug(PLUGIN_NAME, "plugin is succesfully initialized [plugin mode]");
+  iniparser_freedict(ini);
+  return;
+}

Added: trafficserver/plugins/mysql_remap/sample.ini
URL: http://svn.apache.org/viewvc/trafficserver/plugins/mysql_remap/sample.ini?rev=1036750&view=auto
==============================================================================
--- trafficserver/plugins/mysql_remap/sample.ini (added)
+++ trafficserver/plugins/mysql_remap/sample.ini Fri Nov 19 07:17:55 2010
@@ -0,0 +1,6 @@
+[mysql_remap]
+mysql_host     = localhost   #default
+mysql_port     = 3306        #default
+mysql_username = root
+mysql_password = 
+mysql_database = mysql_remap #default

Added: trafficserver/plugins/mysql_remap/schema/import.sql
URL: http://svn.apache.org/viewvc/trafficserver/plugins/mysql_remap/schema/import.sql?rev=1036750&view=auto
==============================================================================
--- trafficserver/plugins/mysql_remap/schema/import.sql (added)
+++ trafficserver/plugins/mysql_remap/schema/import.sql Fri Nov 19 07:17:55 2010
@@ -0,0 +1,116 @@
+-- MySQL dump 10.13  Distrib 5.1.48, for apple-darwin10.4.0 (i386)
+--
+-- Host: localhost    Database: mysql_remap
+-- ------------------------------------------------------
+-- Server version	5.1.48-log
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `hostname`
+--
+
+DROP TABLE IF EXISTS `hostname`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `hostname` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `hostname` varchar(255) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `hostname` (`hostname`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `hostname`
+--
+
+LOCK TABLES `hostname` WRITE;
+/*!40000 ALTER TABLE `hostname` DISABLE KEYS */;
+INSERT INTO `hostname` VALUES (1,'www.ericbalsa.com'),(2,'www.google.com');
+/*!40000 ALTER TABLE `hostname` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `map`
+--
+
+DROP TABLE IF EXISTS `map`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `map` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `from_scheme_id` int(10) unsigned NOT NULL DEFAULT '1',
+  `from_hostname_id` int(10) unsigned NOT NULL,
+  `from_port` int(5) unsigned NOT NULL,
+  `to_scheme_id` int(10) unsigned NOT NULL DEFAULT '1',
+  `to_hostname_id` int(10) unsigned NOT NULL,
+  `to_port` int(5) unsigned NOT NULL DEFAULT '80',
+  `is_enabled` tinyint(1) unsigned NOT NULL DEFAULT '1',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `from_unique` (`from_scheme_id`,`from_hostname_id`,`from_port`),
+  UNIQUE KEY `to_unique` (`to_scheme_id`,`to_hostname_id`,`to_port`),
+  UNIQUE KEY `unique_across_everything` (`from_scheme_id`,`from_hostname_id`,`from_port`,`to_scheme_id`,`to_hostname_id`,`to_port`),
+  KEY `to_hostname_id` (`to_hostname_id`),
+  KEY `from_hostname_id` (`from_hostname_id`),
+  CONSTRAINT `map_ibfk_1` FOREIGN KEY (`from_scheme_id`) REFERENCES `scheme` (`id`) ON UPDATE CASCADE,
+  CONSTRAINT `map_ibfk_3` FOREIGN KEY (`to_scheme_id`) REFERENCES `scheme` (`id`) ON UPDATE CASCADE,
+  CONSTRAINT `map_ibfk_4` FOREIGN KEY (`to_hostname_id`) REFERENCES `hostname` (`id`) ON UPDATE CASCADE,
+  CONSTRAINT `map_ibfk_5` FOREIGN KEY (`from_hostname_id`) REFERENCES `hostname` (`id`) ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `map`
+--
+
+LOCK TABLES `map` WRITE;
+/*!40000 ALTER TABLE `map` DISABLE KEYS */;
+INSERT INTO `map` VALUES (1,1,2,80,1,1,80,1);
+/*!40000 ALTER TABLE `map` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `scheme`
+--
+
+DROP TABLE IF EXISTS `scheme`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `scheme` (
+  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `scheme_desc` varchar(5) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `desc` (`scheme_desc`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `scheme`
+--
+
+LOCK TABLES `scheme` WRITE;
+/*!40000 ALTER TABLE `scheme` DISABLE KEYS */;
+INSERT INTO `scheme` VALUES (1,'http'),(2,'https');
+/*!40000 ALTER TABLE `scheme` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2010-11-15 21:08:43

Propchange: trafficserver/plugins/mysql_remap/schema/import.sql
------------------------------------------------------------------------------
    svn:eol-style = native