1
0
Fork 0

Fix: Immediate fetch and store of missing UAProf data on demand

This commit is contained in:
bagyenda 2006-02-24 13:29:24 +00:00
parent cba8424eef
commit e13422bab4
2 changed files with 82 additions and 101 deletions

View File

@ -37,7 +37,7 @@ struct MmsUaProfile {
}; };
static Dict *profile_dict; /* Of MmsUaProfile *. */ static Dict *profile_dict; /* Of MmsUaProfile *. */
static HTTPCaller *client; static Octstr *profile_dir; /* Directory for storing data. */
/* Hash function -- case insensitive. */ /* Hash function -- case insensitive. */
static unsigned long hash_key(Octstr *s) static unsigned long hash_key(Octstr *s)
@ -429,59 +429,62 @@ static int mms_load_ua_profile_cache(char *dir)
} }
static void mms_profile_fetcher(char *cache_dir) static MmsUaProfile *profile_fetch(Octstr *profile_url)
{ {
Octstr *profile_url, *final_url, *body; Octstr *final_url = NULL, *body = NULL;
List *h; List *h, *rh = NULL;
int status; int status;
MmsUaProfile *prof;
/* Just keep getting the data and putting it in the cache and on file. */
client = http_caller_create(); gw_assert(profile_dict);
debug("mms.uaprof", 0, "Entered fetcher"); debug("mms.uaprof", 0, "Entered fetcher");
while ((profile_url = http_receive_result(client, &status, &final_url, &h, &body)) != NULL) {
if (status == HTTP_OK) {
MmsUaProfile *prof = parse_uaprofile(body);
Octstr *fname;
FILE *f;
debug("mms.uaprof", 0, "Fetcher got %s", octstr_get_cstr(profile_url));
if (prof) { if ((prof = dict_get(profile_dict, profile_url)) != NULL)
if (dict_put_once(profile_dict, profile_url, prof) != 1) return prof;
warning(0, "mms_uaprof: Duplicate ua profile fetched? (%s)?\n",
octstr_get_cstr(profile_url));
} else {
error(0, "mms_uaprof: Failed to parse UA prof url=%s\n",
octstr_get_cstr(profile_url));
goto loop;
}
octstr_convert_range(profile_url, 0, octstr_len(profile_url), replace_slash);
fname = octstr_format("%.255s/%.254s", cache_dir, octstr_get_cstr(profile_url));
f = fopen(octstr_get_cstr(fname), "w");
if (f) {
octstr_print(f, body);
fclose(f);
} else
error(0, "mms_uaprof: Failed to save profile data to cache file %s->%s\n",
octstr_get_cstr(fname), strerror(errno));
octstr_destroy(fname);
}
loop:
if (body) octstr_destroy(body);
if (profile_url) octstr_destroy(profile_url);
if (h) http_destroy_headers(h);
if (final_url) octstr_destroy(final_url);
}
debug("mms.uaprof", 0, "Fetcher shutdown..."); h = http_create_empty_headers();
http_caller_destroy(client); http_header_add(h, "User-Agent", MM_NAME "/" MMSC_VERSION);
client = NULL;
dict_destroy(profile_dict); status = http_get_real(HTTP_METHOD_GET, profile_url, h, &final_url, &rh, &body);
profile_dict = NULL; if (status == HTTP_OK) {
prof = parse_uaprofile(body);
debug("mms.uaprof", 0, "Fetcher got %s", octstr_get_cstr(profile_url));
if (prof) {
if (dict_put_once(profile_dict, profile_url, prof) != 1)
warning(0, "mms_uaprof: Duplicate ua profile fetched? (%s)?\n",
octstr_get_cstr(profile_url));
else {
Octstr *fname;
FILE *f;
octstr_convert_range(profile_url, 0, octstr_len(profile_url), replace_slash);
fname = octstr_format("%.255s/%.254s", octstr_get_cstr(profile_dir),
octstr_get_cstr(profile_url));
f = fopen(octstr_get_cstr(fname), "w");
if (f) {
octstr_print(f, body);
fclose(f);
} else
error(0, "mms_uaprof: Failed to save profile data to cache file %s->%s\n",
octstr_get_cstr(fname), strerror(errno));
octstr_destroy(fname);
}
} else
error(0, "mms_uaprof: Failed to parse UA prof url=%s\n",
octstr_get_cstr(profile_url));
} else
prof = NULL;
if (body) octstr_destroy(body);
if (h) http_destroy_headers(h);
if (rh) http_destroy_headers(rh);
if (final_url) octstr_destroy(final_url);
return prof;
} }
static void init_format_table(void); static void init_format_table(void);
@ -491,16 +494,17 @@ int mms_start_profile_engine(char *cache_dir)
init_profiledict(); init_profiledict();
init_format_table(); init_format_table();
mms_load_ua_profile_cache(cache_dir); mms_load_ua_profile_cache(cache_dir);
gwthread_create((gwthread_func_t *)mms_profile_fetcher, cache_dir); profile_dir = octstr_create(cache_dir);
return 0; return 0;
} }
int mms_stop_profile_engine(void) int mms_stop_profile_engine(void)
{ {
if (client)
http_caller_signal_shutdown(client);
/* This will cause thread to stop and also destroy dict. */ /* This will cause thread to stop and also destroy dict. */
if (profile_dir)
octstr_destroy(profile_dir);
dict_destroy(profile_dict);
return 0; return 0;
} }
@ -508,29 +512,9 @@ MmsUaProfile *mms_get_ua_profile(char *url)
{ {
Octstr *s = octstr_create(url); Octstr *s = octstr_create(url);
MmsUaProfile *prof = NULL; MmsUaProfile *prof = NULL;
List *h;
gw_assert(profile_dict);
if (!profile_dict) { prof = profile_fetch(s);
error(0, "mms_uaprof: get_profile, cache not set!\n");
goto done;
}
if ((prof = dict_get(profile_dict, s)) != NULL)
goto done;
/* Not found, queue get and return NULL. */
if (client) {
h = http_create_empty_headers();
http_header_add(h, "User-Agent", MM_NAME "/" MMSC_VERSION);
http_start_request(client,HTTP_METHOD_GET, s, h, NULL, 1, octstr_duplicate(s), NULL);
http_destroy_headers(h);
} else
error(0, "mms_uaprof: get_profile, Fetch thread not started!\n");
done:
octstr_destroy(s); octstr_destroy(s);
return prof; return prof;
} }

View File

@ -22,6 +22,7 @@
#include "mmsc_cfg.h" #include "mmsc_cfg.h"
#include "mms_mm7soap.h" #include "mms_mm7soap.h"
#define MAX_MESSAGE_SIZE 100*1024
typedef struct MmsHTTPClientInfo { typedef struct MmsHTTPClientInfo {
HTTPClient *client; HTTPClient *client;
@ -31,7 +32,7 @@ typedef struct MmsHTTPClientInfo {
Octstr *url; Octstr *url;
Octstr *body; Octstr *body;
List *cgivars; List *cgivars;
MmsUaProfile *prof; Octstr *profile_url;
Octstr *base_client_addr; Octstr *base_client_addr;
Octstr *client_addr; Octstr *client_addr;
MmsVasp *vasp; MmsVasp *vasp;
@ -123,32 +124,17 @@ int main(int argc, char *argv[])
&h.body, &h.cgivars)) != NULL) &h.body, &h.cgivars)) != NULL)
if (is_allowed_ip(settings->allow_ip, settings->deny_ip, h.ip)) { if (is_allowed_ip(settings->allow_ip, settings->deny_ip, h.ip)) {
MmsHTTPClientInfo *hx = gw_malloc(sizeof *hx); MmsHTTPClientInfo *hx = gw_malloc(sizeof *hx);
Octstr *profile_url;
h.vasp = NULL; h.vasp = NULL;
h.prof = NULL; h.profile_url = NULL;
h.ua = http_header_value(h.headers, octstr_imm("User-Agent")); h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
/* Get the profile URL and store it. Has effect of fetching if missing. */ /* Get the profile URL and store it. Has effect of fetching if missing. */
if ((profile_url = http_header_value(h.headers, if ((h.profile_url = http_header_value(h.headers,
octstr_imm("X-Wap-Profile"))) == NULL) octstr_imm("X-Wap-Profile"))) == NULL)
profile_url = http_header_value(h.headers, octstr_imm("Profile")); h.profile_url = http_header_value(h.headers, octstr_imm("Profile"));
if (profile_url) { octstr_strip_nonalphanums(h.profile_url);
octstr_strip_nonalphanums(profile_url);
h.prof = mms_get_ua_profile(octstr_get_cstr(profile_url));
octstr_destroy(profile_url);
}
/* In case profile_url is missing or we haven't cached it yet,
* use a fall back strategy and construct profile from HTTP headers.
* XXX: Do we need to make mms_get_ua_profile()
* construct profile even if it's not cached?
*/
if (!h.prof)
h.prof = mms_make_ua_profile(h.headers);
/* Get the sender address. */ /* Get the sender address. */
h.base_client_addr = mms_find_sender_msisdn(h.url, h.base_client_addr = mms_find_sender_msisdn(h.url,
@ -245,7 +231,8 @@ void fetchmms_proxy(MmsHTTPClientInfo *h)
List *rh; List *rh;
char *notify_cmd = NULL, *notify_arg = NULL; char *notify_cmd = NULL, *notify_arg = NULL;
int loc, menc = MS_1_1; int loc, menc = MS_1_1;
MmsUaProfile *prof = NULL;
debug("proxy.fetchinterface", 0, " ---> Entered fetch interface <---"); debug("proxy.fetchinterface", 0, " ---> Entered fetch interface <---");
rh = http_create_empty_headers(); rh = http_create_empty_headers();
@ -258,7 +245,13 @@ void fetchmms_proxy(MmsHTTPClientInfo *h)
octstr_get_cstr(h->ip)); octstr_get_cstr(h->ip));
goto failed; goto failed;
} }
if (h->profile_url) {
prof = mms_get_ua_profile(octstr_get_cstr(h->profile_url));
if (!prof)
prof = mms_make_ua_profile(h->headers);
}
if (loc == MMS_LOC_MQUEUE) { /* where is the message? */ if (loc == MMS_LOC_MQUEUE) { /* where is the message? */
e = mms_queue_readenvelope(octstr_get_cstr(qf), e = mms_queue_readenvelope(octstr_get_cstr(qf),
octstr_get_cstr(settings->mm1_queuedir), 1); octstr_get_cstr(settings->mm1_queuedir), 1);
@ -296,7 +289,7 @@ void fetchmms_proxy(MmsHTTPClientInfo *h)
transid = mms_maketransid(octstr_get_cstr(qf), settings->host_alias); transid = mms_maketransid(octstr_get_cstr(qf), settings->host_alias);
if (settings->content_adaptation) { if (settings->content_adaptation) {
MmsMsg *outmsg = NULL; MmsMsg *outmsg = NULL;
int x = mms_transform_msg(m, h->prof, &outmsg); int x = mms_transform_msg(m, prof, &outmsg);
if (x == -1) { /* Temporary failure, we need to fetch profile. */ if (x == -1) { /* Temporary failure, we need to fetch profile. */
mr = mms_retrieveconf(NULL, transid, "Error-transient-failure", mr = mms_retrieveconf(NULL, transid, "Error-transient-failure",
@ -1351,7 +1344,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
char *err = "Ok"; char *err = "Ok";
Octstr *x; Octstr *x;
int start, limit; int start, limit;
MmsUaProfile *prof = NULL;
if (!h->client_addr) { if (!h->client_addr) {
error(0, "MMS Send interface (view): failed to find sender address in request from %s!", error(0, "MMS Send interface (view): failed to find sender address in request from %s!",
@ -1405,9 +1398,10 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
/* Should we add the filter and limit headers to otherhdrs? /* Should we add the filter and limit headers to otherhdrs?
* why bother when send knows them? * why bother when send knows them?
*/ */
if (h->prof) { if (h->profile_url &&
(prof = mms_get_ua_profile(octstr_get_cstr(h->profile_url))) != NULL) {
int i, n; int i, n;
for (i = 0, n = msgs ? list_len(msgs) : 0; i<n; i++) { /* Make message references. */ for (i = 0, n = msgs ? list_len(msgs) : 0; i<n; i++) { /* Make message references. */
Octstr *x = list_get(msgs, i); Octstr *x = list_get(msgs, i);
Octstr *sdf = NULL, *token = NULL; Octstr *sdf = NULL, *token = NULL;
@ -1448,7 +1442,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
(MmsMsgGetFunc_t *)mms_mmbox_get, (MmsMsgGetFunc_t *)mms_mmbox_get,
octstr_get_cstr(settings->mmbox_rootdir), octstr_get_cstr(settings->mmbox_rootdir),
octstr_get_cstr(h->client_addr), octstr_get_cstr(h->client_addr),
mms_ua_maxmsgsize(h->prof), prof ? mms_ua_maxmsgsize(prof) : MAX_MESSAGE_SIZE,
MS_1_2, MS_1_2,
otherhdrs); otherhdrs);
reply_body = mms_tobinary(mresp); reply_body = mms_tobinary(mresp);
@ -1926,7 +1920,7 @@ static void mm7proxy(void *unused)
/* Clear some stuff. */ /* Clear some stuff. */
h.client_addr = NULL; h.client_addr = NULL;
h.base_client_addr = NULL; h.base_client_addr = NULL;
h.prof = NULL; h.profile_url = NULL;
/* Get the MM7 sender address. */ /* Get the MM7 sender address. */
h.vasp = find_mm7sender(h.headers, settings->vasp_list); h.vasp = find_mm7sender(h.headers, settings->vasp_list);
@ -1993,6 +1987,9 @@ static void free_clientInfo(MmsHTTPClientInfo *h, int freeh)
if (h->headers) if (h->headers)
http_destroy_headers(h->headers); http_destroy_headers(h->headers);
if (h->profile_url)
octstr_destroy(h->profile_url);
if (freeh) if (freeh)
gw_free(h); gw_free(h);