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 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue