Fix: Immediate fetch and store of missing UAProf data on demand
This commit is contained in:
parent
cba8424eef
commit
e13422bab4
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue