/** SERVER or CLIENT */
enum OSRF_SESSION_TYPE type;
+ /** the current locale for this session **/
+ char* session_locale;
+
/* let the user use the session to store their own session data */
void* userData;
osrf_app_session* osrf_app_server_session_init(
char* session_id, char* our_app, char* remote_id );
+/** sets the default locale for a session **/
+char* osrf_app_session_set_locale( osrf_app_session*, const char* );
+
/** returns a session from the global session hash */
osrf_app_session* osrf_app_session_find_session( char* session_id );
osrf_app_session* session, jsonObject* params,
char* method_name, int protocol, string_array* param_strings);
+int osrfAppSessionMakeLocaleRequest(
+ osrf_app_session* session, jsonObject* params,
+ char* method_name, int protocol, string_array* param_strings, char* locale);
+
+int osrf_app_session_make_locale_req(
+ osrf_app_session* session, jsonObject* params,
+ char* method_name, int protocol, string_array* param_strings, char* locale);
+
/** Sets the given request to complete state */
void osrf_app_session_set_complete( osrf_app_session* session, int request_id );
char* full_param_string;
+ /* magical LOCALE hint */
+ char* sender_locale;
+
+ /* timezone offset from GMT of sender, in seconds */
+ int sender_tz_offset;
+
};
typedef struct osrf_message_struct osrf_message;
typedef struct osrf_message_struct osrfMessage;
+/* Set the locale hint for this message.
+ default_locale is used if not set.
+ Returns NULL if msg or locale is not set, char* to msg->sender_locale on success.
+*/
+char* osrf_message_set_locale( osrf_message* msg, const char* locale );
+
+/* Set the default locale hint to be used for future outgoing messages.
+ Returns NULL if locale is NULL, const char* to default_locale otherwise.
+*/
+const char* osrf_message_set_default_locale( const char* locale );
+
+/* Get the current locale hint -- either the default or most recently received locale.
+ Returns const char* to current_locale.
+*/
+const char* osrf_message_get_current_locale(void);
osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol );
//void osrf_message_set_request_info( osrf_message*, char* param_name, json* params );
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
+#include <strings.h>
#define MODULE_NAME "osrf_json_gateway_module"
#define GATEWAY_CONFIG "OSRFGatewayConfig"
+#define DEFAULT_LOCALE "OSRFDefaultLocale"
#define CONFIG_CONTEXT "gateway"
#define JSON_PROTOCOL "OSRFGatewayLegacyJSON"
#define GATEWAY_USE_LEGACY_JSON 1
module AP_MODULE_DECLARE_DATA osrf_json_gateway_module;
+char* osrf_json_default_locale = "en-US";
char* osrf_json_gateway_config_file = NULL;
int bootstrapped = 0;
int numserved = 0;
osrfStringArray* allowedServices = NULL;
+static const char* osrf_json_gateway_set_default_locale(cmd_parms *parms, void *config, const char *arg) {
+ osrf_json_default_locale = (char*) arg;
+ return NULL;
+}
+
static const char* osrf_json_gateway_set_config(cmd_parms *parms, void *config, const char *arg) {
osrf_json_gateway_config *cfg;
cfg = ap_get_module_config(parms->server->module_config, &osrf_json_gateway_module);
static const command_rec osrf_json_gateway_cmds[] = {
AP_INIT_TAKE1( GATEWAY_CONFIG, osrf_json_gateway_set_config,
NULL, RSRC_CONF, "osrf json gateway config file"),
+ AP_INIT_TAKE1( DEFAULT_LOCALE, osrf_json_gateway_set_default_locale,
+ NULL, RSRC_CONF, "osrf json gateway default locale"),
AP_INIT_TAKE1( JSON_PROTOCOL, osrf_json_gateway_set_json_proto,
NULL, ACCESS_CONF, "osrf json gateway config file"),
{NULL}
osrfLogSetAppname("osrf_json_gw");
+ char* osrf_locale = NULL;
+ char* param_locale = NULL; /* locale for this call */
char* service = NULL; /* service to connect to */
char* method = NULL; /* method to perform */
char* format = NULL; /* method to perform */
osrfLogDebug(OSRF_LOG_MARK, "osrf gateway: parsing URL params");
string_array* mparams = NULL;
string_array* params = apacheParseParms(r); /* free me */
+ param_locale = apacheGetFirstParamValue( params, "locale" );
service = apacheGetFirstParamValue( params, "service" );
method = apacheGetFirstParamValue( params, "method" );
format = apacheGetFirstParamValue( params, "format" );
int ret = OK;
+ /* ----------------------------------------------------------------- */
+ /* Grab the requested locale using the Accept-Language header*/
+
+
+ if ( !param_locale ) {
+ if ( apr_table_get(r->headers_in, "X-OpenSRF-Language") ) {
+ param_locale = strdup( apr_table_get(r->headers_in, "X-OpenSRF-Language") );
+ } else if ( apr_table_get(r->headers_in, "Accept-Language") ) {
+ param_locale = strdup( apr_table_get(r->headers_in, "Accept-Language") );
+ }
+ }
+
+
+ if (param_locale) {
+ growing_buffer* osrf_locale_buf = buffer_init(16);
+ if (index(param_locale, ',')) {
+ int ind = index(param_locale, ',') - param_locale;
+ int i;
+ for ( i = 0; i < ind - 1 && i < 128; i++ )
+ buffer_add_char( osrf_locale_buf, param_locale[i] );
+ } else {
+ buffer_add( osrf_locale_buf, param_locale );
+ }
+
+ free(param_locale);
+ osrf_locale = buffer_release( osrf_locale_buf );
+ } else {
+ osrf_locale = strdup( osrf_json_default_locale );
+ }
+ /* ----------------------------------------------------------------- */
+
+
if(!(service && method) ||
!osrfStringArrayContains(allowedServices, service)) {
*/
osrfAppSession* session = osrf_app_client_session_init(service);
+ osrf_app_session_set_locale(session, osrf_locale);
double starttime = get_timestamp_millis();
int req_id = -1;
if (isXML) {
output = jsonObjectToXML( res );
} else {
- //output = jsonObjectToJSON( res );
output = jsonToStringFunc( res );
if( morethan1 ) ap_rputs(",", r); /* comma between JSON array items */
}
snprintf(bb, l, "%s : %s", statusname, statustext);
jsonObject* tmp = jsonNewObject(bb);
char* j = jsonToStringFunc(tmp);
- //char* j = jsonObjectToJSON(tmp);
snprintf( buf, l, ",\"debug\": %s", j);
free(j);
jsonObjectFree(tmp);
}
osrfLogInfo(OSRF_LOG_MARK, "Completed processing service=%s, method=%s", service, method);
+ free(osrf_locale);
string_array_destroy(params);
string_array_destroy(mparams);
#include <opensrf/osrf_system.h>
-//#include <opensrf/osrf_hash.h>
-//#include <opensrf/osrf_list.h>
int main( int argc, char* argv[] ) {
osrf_app_session* osrf_app_client_session_init( char* remote_service ) {
+ if (!remote_service) {
+ osrfLogWarning( OSRF_LOG_MARK, "No remote service specified in osrf_app_client_session_init");
+ return NULL;
+ }
+
osrf_app_session* session = safe_malloc(sizeof(osrf_app_session));
session->transport_handle = osrf_system_get_transport_client();
return NULL;
}
- char target_buf[512];
- target_buf[ 0 ] = '\0';
-
osrfStringArray* arr = osrfNewStringArray(8);
osrfConfigGetValueList(NULL, arr, "/domains/domain");
char* domain = osrfStringArrayGetString(arr, 0);
+
+ if (!domain) {
+ osrfLogWarning( OSRF_LOG_MARK, "No domains specified in the OpenSRF config file");
+ free( session );
+ osrfStringArrayFree(arr);
+ return NULL;
+ }
+
char* router_name = osrfConfigGetValue(NULL, "/router_name");
-
+ if (!router_name) {
+ osrfLogWarning( OSRF_LOG_MARK, "No router name specified in the OpenSRF config file");
+ free( session );
+ osrfStringArrayFree(arr);
+ return NULL;
+ }
+
+ char target_buf[512];
+ target_buf[ 0 ] = '\0';
+
int len = snprintf( target_buf, 512, "%s@%s/%s",
router_name ? router_name : "(null)",
domain ? domain : "(null)",
osrfApplication* app = safe_malloc(sizeof(osrfApplication));
app->handle = dlopen (soFile, RTLD_NOW);
- app->onExit = NULL;
+ app->onExit = NULL;
if(!app->handle) {
osrfLogWarning( OSRF_LOG_MARK, "Failed to dlopen library file %s: %s", soFile, dlerror() );
osrfLogSetAppname(appName);
- osrfAppSetOnExit(app, appName);
+ osrfAppSetOnExit(app, appName);
return 0;
}
void osrfAppSetOnExit(osrfApplication* app, char* appName) {
- if(!(app && appName)) return;
+ if(!(app && appName)) return;
/* see if we can run the initialize method */
- char* error;
+ char* error;
void (*onExit) (void);
*(void **) (&onExit) = dlsym(app->handle, "osrfAppChildExit");
if( (error = dlerror()) != NULL ) {
- osrfLogDebug(OSRF_LOG_MARK, "No exit handler defined for %s", appName);
- return;
- }
+ osrfLogDebug(OSRF_LOG_MARK, "No exit handler defined for %s", appName);
+ return;
+ }
- osrfLogInfo(OSRF_LOG_MARK, "registering exit handler for %s", appName);
- app->onExit = (*onExit);
- //if( (ret = (*onExit)()) ) {
+ osrfLogInfo(OSRF_LOG_MARK, "registering exit handler for %s", appName);
+ app->onExit = (*onExit);
}
void osrfAppRunExitCode() {
- osrfHashIterator* itr = osrfNewHashIterator(__osrfAppHash);
- osrfApplication* app;
- while( (app = osrfHashIteratorNext(itr)) ) {
- if( app->onExit ) {
- osrfLogInfo(OSRF_LOG_MARK, "Running onExit handler for app %s", itr->current);
- app->onExit();
- }
- }
+ osrfHashIterator* itr = osrfNewHashIterator(__osrfAppHash);
+ osrfApplication* app;
+ while( (app = osrfHashIteratorNext(itr)) ) {
+ if( app->onExit ) {
+ osrfLogInfo(OSRF_LOG_MARK, "Running onExit handler for app %s", itr->current);
+ app->onExit();
+ }
+ }
}
#include <opensrf/osrf_message.h>
+static char default_locale[17] = "en-US\0\0\0\0\0\0\0\0\0\0\0\0";
+static char* current_locale = default_locale;
+
osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
osrf_message* msg = (osrf_message*) safe_malloc(sizeof(osrf_message));
msg->is_exception = 0;
msg->_params = NULL;
msg->_result_content = NULL;
+ msg->sender_locale = NULL;
return msg;
}
+const char* osrf_message_get_last_locale() {
+ return current_locale;
+}
+
+char* osrf_message_set_locale( osrf_message* msg, const char* locale ) {
+ if( msg == NULL || locale == NULL ) return NULL;
+ return msg->sender_locale = strdup( locale );
+}
+
+const char* osrf_message_set_default_locale( const char* locale ) {
+ if( locale == NULL ) return NULL;
+ if( strlen(locale) > 16 ) return NULL;
+
+ memcpy( default_locale, locale, strlen(locale) );
+ default_locale[strlen(locale)] = '\0';
+ return (const char*) default_locale;
+}
+
void osrf_message_set_method( osrf_message* msg, char* method_name ) {
if( msg == NULL || method_name == NULL ) return;
msg->method_name = strdup( method_name );
if( msg->method_name != NULL )
free(msg->method_name);
+ if( msg->sender_locale != NULL )
+ free(msg->sender_locale);
+
if( msg->_params != NULL )
jsonObjectFree(msg->_params);
INT_TO_STRING(msg->thread_trace);
jsonObjectSetKey(json, "threadTrace", jsonNewObject(INTSTR));
+ if (msg->sender_locale != NULL) {
+ jsonObjectSetKey(json, "locale", jsonNewObject(msg->sender_locale));
+ } else if (current_locale != NULL) {
+ jsonObjectSetKey(json, "locale", jsonNewObject(current_locale));
+ } else {
+ jsonObjectSetKey(json, "locale", jsonNewObject(default_locale));
+ }
+
switch(msg->m_type) {
case CONNECT:
new_msg->thread_trace = atoi(tt);
free(tt);
}
- /*
- if(tmp->type == JSON_NUMBER)
- new_msg->thread_trace = (int) jsonObjectGetNumber(tmp);
- if(tmp->type == JSON_STRING)
- new_msg->thread_trace = atoi(jsonObjectGetString(tmp));
- */
}
+ /* use the sender's locale, or the global default */
+ tmp = jsonObjectGetKey(message, "locale");
+ if(tmp)
+ new_msg->sender_locale = jsonObjectToSimpleString(tmp);
+
+ current_locale = new_msg->sender_locale;
tmp = jsonObjectGetKey(message, "protocol");
new_msg->protocol = atoi(proto);
free(proto);
}
-
- /*
- if(tmp->type == JSON_NUMBER)
- new_msg->protocol = (int) jsonObjectGetNumber(tmp);
- if(tmp->type == JSON_STRING)
- new_msg->protocol = atoi(jsonObjectGetString(tmp));
- */
}
tmp = jsonObjectGetKey(message, "payload");
return $self->{'last_sent_payload'};
}
+sub session_locale {
+ my( $self, $type ) = @_;
+ if( $type ) {
+ return $self->{'session_locale'} = $type;
+ }
+ return $self->{'session_locale'};
+}
+
sub last_sent_type {
my( $self, $type ) = @_;
if( $type ) {
}
# When we're a client and we want to connect to a remote service
-# create( $app, username => $user, secret => $passwd );
-# OR
-# create( $app, sysname => $user, secret => $shared_secret );
sub create {
my $class = shift;
$class = ref($class) || $class;
my $app = shift;
my $api_level = shift;
my $quiet = shift;
+ my $locale = shift;
$api_level = 1 if (!defined($api_level));
session_id => $sess_id,
remote_id => $r_id,
raise_error => $quiet ? 0 : 1,
+ session_locale => $locale,
api_level => $api_level,
orig_remote_id => $r_id,
peer_handle => $peer_handle,
$msg->api_level($self->api_level);
$msg->payload($payload) if $payload;
+ $msg->sender_locale($self->session_locale) if $self->session_locale;
push @doc, $msg;
$logger->debug( "Number of matched responses: " . @list, DEBUG );
$self->queue_wait(0); # check for statuses
- return $list[0] unless (wantarray);
+ if (!wantarray) {
+ $self->session_locale( $list[0]->sender_locale );
+ return $list[0];
+ } else {
+ $self->session_locale( $list[-1]->sender_locale );
+ }
+
return @list;
}
return $self->{api_level};
}
+=head2 OpenSRF::DomainObject::oilsMessage->sender_locale( [$locale] );
+
+=over 4
+
+Sets or gets the current message locale hint. Useful for telling the
+server how you see the world.
+
+=back
+
+=cut
+
+sub sender_locale {
+ my $self = shift;
+ my $val = shift;
+ $self->{sender_locale} = $val if (defined $val);
+ return $self->{sender_locale};
+}
+
=head2 OpenSRF::DomainObject::oilsMessage->threadTrace( [$new_threadTrace] );
=over 4