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 HTTPCaller *client;
static Octstr *profile_dir; /* Directory for storing data. */
/* Hash function -- case insensitive. */
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;
List *h;
Octstr *final_url = NULL, *body = NULL;
List *h, *rh = NULL;
int status;
/* Just keep getting the data and putting it in the cache and on file. */
client = http_caller_create();
MmsUaProfile *prof;
gw_assert(profile_dict);
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 (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 {
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);
}
if ((prof = dict_get(profile_dict, profile_url)) != NULL)
return prof;
debug("mms.uaprof", 0, "Fetcher shutdown...");
http_caller_destroy(client);
client = NULL;
h = http_create_empty_headers();
http_header_add(h, "User-Agent", MM_NAME "/" MMSC_VERSION);
dict_destroy(profile_dict);
profile_dict = NULL;
status = http_get_real(HTTP_METHOD_GET, profile_url, h, &final_url, &rh, &body);
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);
@ -491,16 +494,17 @@ int mms_start_profile_engine(char *cache_dir)
init_profiledict();
init_format_table();
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;
}
int mms_stop_profile_engine(void)
{
if (client)
http_caller_signal_shutdown(client);
/* This will cause thread to stop and also destroy dict. */
if (profile_dir)
octstr_destroy(profile_dir);
dict_destroy(profile_dict);
return 0;
}
@ -508,29 +512,9 @@ MmsUaProfile *mms_get_ua_profile(char *url)
{
Octstr *s = octstr_create(url);
MmsUaProfile *prof = NULL;
List *h;
if (!profile_dict) {
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:
gw_assert(profile_dict);
prof = profile_fetch(s);
octstr_destroy(s);
return prof;
}

View File

@ -22,6 +22,7 @@
#include "mmsc_cfg.h"
#include "mms_mm7soap.h"
#define MAX_MESSAGE_SIZE 100*1024
typedef struct MmsHTTPClientInfo {
HTTPClient *client;
@ -31,7 +32,7 @@ typedef struct MmsHTTPClientInfo {
Octstr *url;
Octstr *body;
List *cgivars;
MmsUaProfile *prof;
Octstr *profile_url;
Octstr *base_client_addr;
Octstr *client_addr;
MmsVasp *vasp;
@ -123,32 +124,17 @@ int main(int argc, char *argv[])
&h.body, &h.cgivars)) != NULL)
if (is_allowed_ip(settings->allow_ip, settings->deny_ip, h.ip)) {
MmsHTTPClientInfo *hx = gw_malloc(sizeof *hx);
Octstr *profile_url;
h.vasp = NULL;
h.prof = NULL;
h.profile_url = NULL;
h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
/* 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)
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(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);
octstr_strip_nonalphanums(h.profile_url);
/* Get the sender address. */
h.base_client_addr = mms_find_sender_msisdn(h.url,
@ -245,7 +231,8 @@ void fetchmms_proxy(MmsHTTPClientInfo *h)
List *rh;
char *notify_cmd = NULL, *notify_arg = NULL;
int loc, menc = MS_1_1;
MmsUaProfile *prof = NULL;
debug("proxy.fetchinterface", 0, " ---> Entered fetch interface <---");
rh = http_create_empty_headers();
@ -258,7 +245,13 @@ void fetchmms_proxy(MmsHTTPClientInfo *h)
octstr_get_cstr(h->ip));
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? */
e = mms_queue_readenvelope(octstr_get_cstr(qf),
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);
if (settings->content_adaptation) {
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. */
mr = mms_retrieveconf(NULL, transid, "Error-transient-failure",
@ -1351,7 +1344,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
char *err = "Ok";
Octstr *x;
int start, limit;
MmsUaProfile *prof = NULL;
if (!h->client_addr) {
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?
* 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;
for (i = 0, n = msgs ? list_len(msgs) : 0; i<n; i++) { /* Make message references. */
Octstr *x = list_get(msgs, i);
Octstr *sdf = NULL, *token = NULL;
@ -1448,7 +1442,7 @@ static void sendmms_proxy(MmsHTTPClientInfo *h)
(MmsMsgGetFunc_t *)mms_mmbox_get,
octstr_get_cstr(settings->mmbox_rootdir),
octstr_get_cstr(h->client_addr),
mms_ua_maxmsgsize(h->prof),
prof ? mms_ua_maxmsgsize(prof) : MAX_MESSAGE_SIZE,
MS_1_2,
otherhdrs);
reply_body = mms_tobinary(mresp);
@ -1926,7 +1920,7 @@ static void mm7proxy(void *unused)
/* Clear some stuff. */
h.client_addr = NULL;
h.base_client_addr = NULL;
h.prof = NULL;
h.profile_url = NULL;
/* Get the MM7 sender address. */
h.vasp = find_mm7sender(h.headers, settings->vasp_list);
@ -1993,6 +1987,9 @@ static void free_clientInfo(MmsHTTPClientInfo *h, int freeh)
if (h->headers)
http_destroy_headers(h->headers);
if (h->profile_url)
octstr_destroy(h->profile_url);
if (freeh)
gw_free(h);