static Octstr *mm7http_send(MmscGrp *mmc, Octstr *from, Octstr *to, MmsMsg *m, Octstr **error, int *retry) { Octstr *ret = NULL; int mtype = mms_messagetype(m); int hstatus = HTTP_OK; List *rh, *ph = NULL; Octstr *body = NULL, *rbody = NULL; Octstr *mms; MIMEEntity *form_data = make_multipart_formdata(); mms_info(0, "MM7", mmc->id, "MMSBox: Send [http] to MMC[%s], msg type [%s], from %s, to %s", mmc ? octstr_get_cstr(mmc->id) : "", mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to)); mms = mms_tobinary(m); add_multipart_form_field(form_data, "to", "text/plain", NULL, to); add_multipart_form_field(form_data, "from", "text/plain", NULL, from); add_multipart_form_field(form_data, "mms", "application/vnd.wap.mms-message", NULL, mms); rh = mime_entity_headers(form_data); body = mime_entity_body(form_data); hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody); if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { *error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !", mmc->mmsc_url, hstatus); } else { ret = rbody ? octstr_duplicate(rbody) : NULL; if (ret) octstr_strip_blanks(ret); } *retry = (ret == NULL && (http_status_class(hstatus) == HTTP_STATUS_SERVER_ERROR || hstatus < 0)); if (ret) mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); http_destroy_headers(rh); octstr_destroy(body); http_destroy_headers(ph); octstr_destroy(rbody); octstr_destroy(mms); mime_entity_destroy(form_data); return ret; }
static int sendNotify(MmsEnvelope *e) { Octstr *to; MmsMsg *msg, *smsg = NULL; MmsEnvelopeTo *xto = gwlist_get(e->to, 0); Octstr *err = NULL; time_t tnow = time(NULL); int j, k, len; Octstr *phonenum = NULL, *rcpt_ip = NULL, *msgId, *from, *fromproxy; int mtype, msize; int res = MMS_SEND_OK, dlr; time_t expiryt; char *prov_notify_event = NULL; char *rtype = NULL; if (e->lastaccess != 0) { /* This message has been fetched at least once, no more signals. */ e->sendt = e->expiryt + 3600*24*30*12; info(0, "MM1: Message [ID: %s] fetched/touched at least once. Skipping", e->xqfname); return settings->qfs->mms_queue_update(e); } if (!xto) { error(0, "mobilesender: Queue entry %s with no recipients!", e->xqfname); return 0; } msg = settings->qfs->mms_queue_getdata(e); to = octstr_duplicate(xto->rcpt); expiryt = e->expiryt; msgId = e->msgId ? octstr_duplicate(e->msgId) : NULL; from = octstr_duplicate(e->from); fromproxy = e->fromproxy ? octstr_duplicate(e->fromproxy) : NULL; msize = e->msize; dlr = e->dlr; if (e->expiryt != 0 && /* Handle message expiry. */ e->expiryt < tnow) { err = octstr_format("MMSC error: Message expired while sending to %S!", to); res = MMS_SEND_ERROR_FATAL; prov_notify_event = "failedfetch"; rtype = "Expired"; goto done; } else if (e->attempts >= settings->maxsendattempts) { err = octstr_format("MMSC error: Failed to deliver to %S after %ld attempts!", to, e->attempts); res = MMS_SEND_ERROR_FATAL; prov_notify_event = "failedfetch"; rtype = "Expired"; goto done; } j = octstr_case_search(to, octstr_imm("/TYPE=PLMN"), 0); k = octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0); len = octstr_len(to); if (j > 0 && j - 1 + sizeof "/TYPE=PLMN" == len) { /* A proper number. */ phonenum = octstr_copy(to, 0, j); #if 0 normalize_number(octstr_get_cstr(settings->unified_prefix), &phonenum); #else mms_normalize_phonenum(&phonenum, octstr_get_cstr(settings->unified_prefix), settings->strip_prefixes); #endif } else if (k > 0 && k + sizeof "/TYPE=IPv" == len) rcpt_ip = octstr_copy(to, 0, k); else { /* We only handle phone numbers here. */ err = octstr_format("Unexpected recipient %s in MT queue!", octstr_get_cstr(to)); res = MMS_SEND_ERROR_FATAL; goto done; } mtype = mms_messagetype(msg); /* For phone, getting here means the message can be delivered. So: * - Check whether the recipient is provisioned, if not, wait (script called will queue creation req) * - If the recipient can't take MMS, then send SMS. */ /* We handle two types of requests: send and delivery/read notifications. * other types of messages cannot possibly be in this queue! */ if (mtype == MMS_MSGTYPE_SEND_REQ || mtype == MMS_MSGTYPE_RETRIEVE_CONF) { Octstr *url, *transid; if (phonenum) { int send_ind = mms_ind_send(settings->prov_getstatus, phonenum); if (send_ind < 0 && settings->notify_unprovisioned) send_ind = 0; if (send_ind < 0) { /* That is, recipient is not (yet) provisioned. */ res = MMS_SEND_ERROR_TRANSIENT; err = octstr_format("%S is not provisioned for MMS reception, delivery deferred!", phonenum); /* Do not increase delivery attempts counter. */ e->lasttry = tnow; e->sendt = e->lasttry + settings->send_back_off * (1 + e->attempts); if (settings->qfs->mms_queue_update(e) == 1) e = NULL; /* Queue entry gone. */ else settings->qfs->mms_queue_free_env(e); goto done; } else if (send_ind == 0) { /* provisioned but does not support */ Octstr *s = octstr_format(octstr_get_cstr(settings->mms_notify_txt), from); if (settings->notify_unprovisioned && s && octstr_len(s) > 0) { /* Only send if the string was set. */ List *pheaders; Octstr *sto = octstr_duplicate(phonenum); octstr_url_encode(s); octstr_url_encode(sto); url = octstr_format("%S&text=%S&to=%S",settings->sendsms_url,s, sto); pheaders = http_create_empty_headers(); http_header_add(pheaders, "Connection", "close"); http_header_add(pheaders, "User-Agent", MM_NAME "/" VERSION); http_start_request(httpcaller, HTTP_METHOD_GET, url, pheaders, NULL, 0, &edummy, NULL); http_destroy_headers(pheaders); octstr_destroy(url); octstr_destroy(sto); } else if (s) octstr_destroy(s); res = MMS_SEND_OK; err = octstr_imm("No MMS Ind support, sent SMS instead"); xto->process = 0; /* No more processing. */ if (settings->qfs->mms_queue_update(e) == 1) e = NULL; else settings->qfs->mms_queue_free_env(e); goto done; } } /* To get here means we can send Ind. */ url = mms_makefetchurl(e->xqfname, e->token, MMS_LOC_MQUEUE, phonenum ? phonenum : to, settings); info(0, "Preparing to notify client to fetch message at URL: %s", octstr_get_cstr(url)); transid = mms_maketransid(e->xqfname, settings->host_alias); smsg = mms_notification(msg, e->msize, url, transid, e->expiryt ? e->expiryt : tnow + settings->default_msgexpiry, settings->optimize_notification_size); octstr_destroy(transid); octstr_destroy(url); } else if (mtype == MMS_MSGTYPE_DELIVERY_IND || mtype == MMS_MSGTYPE_READ_ORIG_IND) smsg = msg; else { error(0, "Unexpected message type %s for %s found in MT queue!", mms_message_type_to_cstr(mtype), octstr_get_cstr(to)); res = MMS_SEND_ERROR_FATAL; goto done; } if (smsg) start_push(phonenum ? phonenum : rcpt_ip, phonenum ? 1 : 0, e, smsg); /* Send the message. * Don't touch 'e' after this point! * It may be freed by receive thread. */ if (smsg != msg && smsg) mms_destroy(smsg); done: if (err != NULL && res != MMS_SEND_ERROR_TRANSIENT) { /* If there was a report request and this is a legit error * queue it. */ if (dlr) { MmsMsg *m = mms_deliveryreport(msgId, to, tnow, rtype ? octstr_imm(rtype) : octstr_imm("Indeterminate")); List *l = gwlist_create(); Octstr *res; gwlist_append(l, from); /* Add to queue, switch via proxy to be from proxy. */ res = settings->qfs->mms_queue_add(to ? to : settings->system_user, l, err, NULL, fromproxy, tnow, tnow+settings->default_msgexpiry, m, NULL, NULL, NULL, NULL, NULL, NULL, 0, octstr_get_cstr(settings->mm1_queuedir), "MM2", settings->host_alias); gwlist_destroy(l, NULL); mms_destroy(m); octstr_destroy(res); } } /* Write to log */ info(0, "%s Mobile Queue MMS Send Notify: From=%s, to=%s, msgsize=%d, reason=%s", SEND_ERROR_STR(res), octstr_get_cstr(from), octstr_get_cstr(to), msize, err ? octstr_get_cstr(err) : ""); if (res == MMS_SEND_ERROR_FATAL) { xto->process = 0; /* No more attempts to deliver, delete this. */ if (settings->qfs->mms_queue_update(e) == 1) e = NULL; /* Queue entry gone. */ else settings->qfs->mms_queue_free_env(e); } /* Else queue will be updated/freed elsewhere. */ if (prov_notify_event) notify_prov_server(octstr_get_cstr(settings->prov_notify), to ? octstr_get_cstr(to) : "unknown", prov_notify_event, rtype ? rtype : "", e ? e->msgId : NULL, NULL, NULL); if (msg) mms_destroy(msg); octstr_destroy(phonenum); octstr_destroy(rcpt_ip); octstr_destroy(to); octstr_destroy(msgId); octstr_destroy(fromproxy); octstr_destroy(from); octstr_destroy(err); return 1; }
static int mm7http_receive(MmsBoxHTTPClientInfo *h) { MmsMsg *m = NULL; List *mh = NULL; int hstatus = HTTP_OK; List *rh = http_create_empty_headers(); Octstr *reply_body = NULL; List *to = NULL; Octstr *hto = NULL, *subject = NULL, *msgid = NULL; Octstr *hfrom = NULL, *body, *rr_uri = NULL, *dlr_uri = NULL; time_t expiryt = -1, deliveryt = -1; Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL, *s; int msize; int dlr, rr; int mtype; List *cgivars_ctypes = NULL, *rqh = http_create_empty_headers(); parse_cgivars(h->headers, h->body, &h->cgivars, &cgivars_ctypes); hfrom = http_cgi_variable(h->cgivars, "from"); hto = http_cgi_variable(h->cgivars, "to"); body = http_cgi_variable(h->cgivars, "mms"); msize = octstr_len(body); debug("mmsbox.mm7http.sendinterface", 0, " --> Enterred http-mmsc send interface, blen=[%d] <--- ", msize); if (hto == NULL) { http_header_add(rh, "Content-Type", "text/plain"); hstatus = HTTP_BAD_REQUEST; reply_body = octstr_format("Missing 'to' argument"); goto done; } else if (hfrom == NULL) { http_header_add(rh, "Content-Type", "text/plain"); hstatus = HTTP_BAD_REQUEST; reply_body = octstr_format("Missing 'from' argument"); goto done; } else if (body == NULL || /* A message is required, and must parse */ (m = mms_frombinary(body, hfrom ? hfrom : octstr_imm("anon@anon"))) == NULL) { http_header_add(rh, "Content-Type", "text/plain"); hstatus = HTTP_BAD_REQUEST; reply_body = octstr_format("Unexpected MMS message, no content?"); goto done; } to = octstr_split_words(hto); mtype = mms_messagetype(m); mh = mms_message_headers(m); /* find interesting headers. */ subject = http_header_value(mh, octstr_imm("Subject")); /* Find expiry and delivery times */ if ((s = http_header_value(mh, octstr_imm("X-Mms-Expiry"))) != NULL) { expiryt = date_parse_http(s); octstr_destroy(s); } else expiryt = time(NULL) + DEFAULT_EXPIRE; if ((s = http_header_value(mh, octstr_imm("X-Mms-Delivery-Time"))) != NULL) { deliveryt = date_parse_http(s); octstr_destroy(s); } else deliveryt = 0; qdir = get_mmsbox_queue_dir(hfrom, to, h->m, &mmc_id); /* get routing info. */ switch(mtype) { Octstr *value, *value2; case MMS_MSGTYPE_SEND_REQ: case MMS_MSGTYPE_RETRIEVE_CONF: /* Get/make a Message ID */ if ((msgid = mms_get_header_value(m, octstr_imm("Message-ID"))) == NULL) { /* Make a message id for it directly. We need it below. */ msgid = mms_make_msgid(NULL, NULL); mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid)); } if ((value = http_header_value(mh, octstr_imm("X-Mms-Delivery-Report"))) != NULL && octstr_case_compare(value, octstr_imm("Yes")) == 0) dlr = 1; else dlr = 0; octstr_destroy(value); if ((value = http_header_value(mh, octstr_imm("X-Mms-Read-Report"))) != NULL && octstr_case_compare(value, octstr_imm("Yes")) == 0) rr = 1; else rr = 0; octstr_destroy(value); if (deliveryt < 0) deliveryt = time(NULL); if (expiryt < 0) expiryt = time(NULL) + DEFAULT_EXPIRE; mms_remove_headers(m, "Bcc"); mms_remove_headers(m, "X-Mms-Delivery-Time"); mms_remove_headers(m, "X-Mms-Expiry"); mms_remove_headers(m, "X-Mms-Sender-Visibility"); MOD_SUBJECT(m, h->m, hfrom); if (qdir == outgoing_qdir) { /* We need to remember the old message ID so we can re-write it * if a DLR is relayed backwards. */ Octstr *t = mms_maketransid(NULL, octstr_imm(MM_NAME)); /* make a fake transaction id so dlr works*/ http_header_add(rqh, "X-Mbuni-TransactionID", octstr_get_cstr(t)); if (dlr) dlr_uri = octstr_format("msgid:%S", msgid); if (rr) rr_uri = octstr_format("msgid:%S", msgid); octstr_destroy(t); } /* Save it, put message id in header, return. */ qf = qfs->mms_queue_add(hfrom, to, subject, h->m->id, mmc_id, deliveryt, expiryt, m, NULL, NULL, NULL, dlr_uri, rr_uri, rqh, dlr, octstr_get_cstr(qdir), "MM7/HTTP-IN", NULL); if (qf) { /* Log to access log */ mms_log("Received", hfrom, to, msize, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_OK; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; break; case MMS_MSGTYPE_DELIVERY_IND: msgid = mms_get_header_value(m, octstr_imm("Message-ID")); value = mms_get_header_value(m, octstr_imm("X-Mms-Status")); value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID")); rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "delivery-report", value, rqh, NULL, 0, msgid); if (mmc_id == NULL && value2) http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2)); qf = qfs->mms_queue_add(hfrom, to, NULL, h->m->id, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, rr_uri, NULL, rqh, 0, octstr_get_cstr(qdir), "MM7/HTTP-IN", NULL); if (qf) { /* Log to access log */ mms_log("DeliveryReport", hfrom, to, -1, msgid,value, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_OK; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; octstr_destroy(value); octstr_destroy(value2); break; case MMS_MSGTYPE_READ_ORIG_IND: msgid = mms_get_header_value(m, octstr_imm("Message-ID")); value = mms_get_header_value(m, octstr_imm("X-Mms-Read-Status")); value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID")); rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "read-report", value, rqh, NULL, 0, msgid); if (mmc_id == NULL && value2) http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2)); qf = qfs->mms_queue_add(hfrom, to, NULL, h->m->id, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, rr_uri, NULL, rqh, 0, octstr_get_cstr(qdir), "MM7/HTTP-IN", NULL); if (qf) { /* Log to access log */ mms_log("Received RR", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_NO_CONTENT; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; octstr_destroy(value); octstr_destroy(value2); break; } done: http_header_add(rh, "X-Mbuni-Version", VERSION); http_send_reply(h->client, hstatus, rh, msgid ? msgid : (qf ? qf : octstr_imm(""))); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); octstr_destroy(subject); octstr_destroy(qf); octstr_destroy(mmc_id); octstr_destroy(msgid); http_destroy_headers(mh); http_destroy_headers(rh); http_destroy_headers(rqh); if (m) mms_destroy(m); http_destroy_cgiargs(cgivars_ctypes); return http_status_class(hstatus) == HTTP_STATUS_SUCCESSFUL ? 0 : -1; }
static int mm7eaif_receive(MmsBoxHTTPClientInfo *h) { MmsMsg *m = NULL; List *mh = NULL; int hstatus = HTTP_NO_CONTENT; List *rh = http_create_empty_headers(); List *rqh = http_create_empty_headers(); Octstr *reply_body = NULL, *value = NULL, *value2 = NULL; List *to = gwlist_create(), *hto = NULL; Octstr *subject = NULL, *otransid = NULL, *msgid = NULL; Octstr *hfrom = NULL, *rr_uri = NULL; time_t expiryt = -1, deliveryt = -1; Octstr *qf = NULL, *xver = NULL, *mmc_id = NULL, *qdir = NULL; int msize = h->body ? octstr_len(h->body) : 0; int dlr; int mtype; debug("mmsbox.mm7eaif.sendinterface", 0, " --> Enterred eaif send interface, blen=[%d] <--- ", msize); hfrom = http_header_value(h->headers, octstr_imm("X-NOKIA-MMSC-From")); if (!h->body || /* A body is required, and must parse */ (m = mms_frombinary(h->body, hfrom ? hfrom : octstr_imm("anon@anon"))) == NULL) { http_header_add(rh, "Content-Type", "text/plain"); hstatus = HTTP_BAD_REQUEST; reply_body = octstr_format("Unexpected MMS message, no body?"); goto done; } /* XXXX handle delivery reports differently. */ mtype = mms_messagetype(m); mh = mms_message_headers(m); /* Now get sender and receiver data. * for now we ignore adaptation flags. */ mms_collect_envdata_from_msgheaders(mh, &to, &subject, &otransid, &expiryt, &deliveryt, DEFAULT_EXPIRE, -1, octstr_get_cstr(unified_prefix), strip_prefixes); if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL && gwlist_len(hto) > 0) { /* To address is in headers. */ int i, n; gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); to = gwlist_create(); for (i = 0, n = gwlist_len(hto); i < n; i++) { Octstr *h = NULL, *v = NULL; List *l; void *x; http_header_get(hto,i, &h, &v); l = http_header_split_value(v); while ((x = gwlist_extract_first(l)) != NULL) gwlist_append(to, x); gwlist_destroy(l, NULL); octstr_destroy(h); octstr_destroy(v); } } qdir = get_mmsbox_queue_dir(hfrom, to, h->m, &mmc_id); /* get routing info. */ switch(mtype) { case MMS_MSGTYPE_SEND_REQ: case MMS_MSGTYPE_RETRIEVE_CONF: /* Get Message ID */ if ((msgid = http_header_value(h->headers, octstr_imm("X-NOKIA-MMSC-Message-Id"))) == NULL) msgid = http_header_value(mh, octstr_imm("Message-ID")); else mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid)); /* replace it in the message.*/ value = http_header_value(mh, octstr_imm("X-Mms-Delivery-Report")); if (value && octstr_case_compare(value, octstr_imm("Yes")) == 0) dlr = 1; else dlr = 0; if (deliveryt < 0) deliveryt = time(NULL); if (expiryt < 0) expiryt = time(NULL) + DEFAULT_EXPIRE; if (hfrom == NULL) hfrom = http_header_value(mh, octstr_imm("From")); mms_remove_headers(m, "Bcc"); mms_remove_headers(m, "X-Mms-Delivery-Time"); mms_remove_headers(m, "X-Mms-Expiry"); mms_remove_headers(m, "X-Mms-Sender-Visibility"); MOD_SUBJECT(m, h->m, hfrom); /* Save it, put message id in header, return. */ qf = qfs->mms_queue_add(hfrom, to, subject, h->m->id, mmc_id, deliveryt, expiryt, m, NULL, NULL, NULL, NULL, NULL, NULL, dlr, octstr_get_cstr(qdir), "MM7/EAIF-IN", NULL); if (qf) { /* Log to access log */ mms_log("Received", hfrom, to, msize, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_NO_CONTENT; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; octstr_destroy(value); octstr_destroy(value2); break; case MMS_MSGTYPE_DELIVERY_IND: msgid = mms_get_header_value(m, octstr_imm("Message-ID")); value = mms_get_header_value(m, octstr_imm("X-Mms-Status")); value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID")); rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "delivery-report", value, rqh, NULL, 0, msgid); if (value2 && mmc_id == NULL) http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2)); qf = qfs->mms_queue_add(hfrom, to, NULL, h->m->id, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, rr_uri, NULL, rqh, 0, octstr_get_cstr(qdir), "MM7/EAIF-IN", NULL); if (qf) { /* Log to access log */ mms_log("DeliveryReport", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_NO_CONTENT; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; octstr_destroy(value); octstr_destroy(value2); break; case MMS_MSGTYPE_READ_ORIG_IND: msgid = mms_get_header_value(m, octstr_imm("Message-ID")); value = mms_get_header_value(m, octstr_imm("X-Mms-Read-Status")); value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID")); rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "read-report", value, rqh, NULL, 0, msgid); if (value2 && mmc_id == NULL) http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2)); qf = qfs->mms_queue_add(hfrom, to, NULL, h->m->id, mmc_id, 0, time(NULL) + default_msgexpiry, m, NULL, NULL, NULL, rr_uri, NULL, rqh, 0, octstr_get_cstr(qdir), "MM7/EAIF-IN", NULL); if (qf) { /* Log to access log */ mms_log("Received RR", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); hstatus = HTTP_NO_CONTENT; } else hstatus = HTTP_INTERNAL_SERVER_ERROR; octstr_destroy(value); octstr_destroy(value2); break; } done: xver = octstr_format(EAIF_VERSION, h->m->ver.major, h->m->ver.minor1); http_header_add(rh, "X-NOKIA-MMSC-Version", octstr_get_cstr(xver)); octstr_destroy(xver); http_send_reply(h->client, hstatus, rh, octstr_imm("")); http_destroy_headers(hto); http_destroy_headers(rqh); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); octstr_destroy(hfrom); octstr_destroy(subject); octstr_destroy(otransid); octstr_destroy(msgid); octstr_destroy(qf); octstr_destroy(mmc_id); octstr_destroy(rr_uri); http_destroy_headers(mh); mms_destroy(m); return http_status_class(hstatus) == HTTP_STATUS_SUCCESSFUL ? 0 : -1; }
static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *transid, char *vasid, List *hdrs, MmsMsg *m, Octstr **error, int *retry) { Octstr *ret = NULL, *resp = NULL; int mtype = mms_messagetype(m); int hstatus = HTTP_OK; List *rh = http_create_empty_headers(), *ph = NULL; Octstr *body = NULL, *rbody = NULL, *xver = NULL; char *msgtype; mms_info(0, "MM7", mmc->id, "MMSBox: Send [eaif] to MMC[%s], msg type [%s], from %s, to %s", mmc ? octstr_get_cstr(mmc->id) : "", mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to)); http_header_remove_all(rh, "X-Mms-Allow-Adaptations"); http_header_add(rh, "X-NOKIA-MMSC-To", octstr_get_cstr(to)); http_header_add(rh, "X-NOKIA-MMSC-From", octstr_get_cstr(from)); xver = octstr_format(EAIF_VERSION, mmc->ver.major, mmc->ver.minor1); http_header_add(rh, "X-NOKIA-MMSC-Version", octstr_get_cstr(xver)); octstr_destroy(xver); if (mtype == MMS_MSGTYPE_SEND_REQ || mtype == MMS_MSGTYPE_RETRIEVE_CONF) { msgtype = "MultiMediaMessage"; mms_make_sendreq(m); /* ensure it is a sendreq. */ } else if (mtype == MMS_MSGTYPE_DELIVERY_IND) msgtype = "DeliveryReport"; else msgtype = "ReadReply"; http_header_add(rh, "X-NOKIA-MMSC-Message-Type", msgtype); if (hdrs) http_header_combine(rh, hdrs); /* If specified, then update and pass on. */ http_header_add(rh, "Content-Type", "application/vnd.wap.mms-message"); /* Patch the message FROM and TO fields. */ mms_replace_header_value(m, "From", octstr_get_cstr(from)); mms_replace_header_value(m, "To", octstr_get_cstr(to)); mms_replace_header_value(m,"X-Mms-Transaction-ID", transid ? octstr_get_cstr(transid) : "000"); body = mms_tobinary(m); hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody); if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { *error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !", mmc->mmsc_url, hstatus); } else { MmsMsg *mresp = rbody ? mms_frombinary(rbody, octstr_imm("anon@anon")) : NULL; resp = octstr_imm("Ok"); if (mresp && mms_messagetype(mresp) == MMS_MSGTYPE_SEND_CONF) resp = mms_get_header_value(mresp, octstr_imm("X-Mms-Response-Status")); if (octstr_case_compare(resp, octstr_imm("ok")) != 0) hstatus = HTTP_STATUS_SERVER_ERROR; /* error. */ else if (mresp) ret = mms_get_header_value(mresp, octstr_imm("Message-ID")); mms_destroy(mresp); } if (hstatus < 0) ret = NULL; else { hstatus = http_status_class(hstatus); if (hstatus == HTTP_STATUS_SERVER_ERROR || hstatus == HTTP_STATUS_CLIENT_ERROR) ret = NULL; else if (!ret) ret = http_header_value(ph, octstr_imm("X-Nokia-MMSC-Message-Id")); } *retry = (ret == NULL && (hstatus == HTTP_STATUS_SERVER_ERROR || hstatus < 0)); if (ret) mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); #if 0 mms_info(0, "MM7", mmc->id,"Sent to MMC[%s], code=[%d], resp=[%s] msgid [%s]", octstr_get_cstr(mmc->id), hstatus, resp ? octstr_get_cstr(resp) : "(none)", ret ? octstr_get_cstr(ret) : "(none)"); #endif http_destroy_headers(rh); octstr_destroy(body); http_destroy_headers(ph); octstr_destroy(rbody); octstr_destroy(resp); return ret; }
/* XXX Returns msgid in mmsc or NULL if error. Caller uses this for DLR issues. * Caller must make sure throughput issues * are observed! * Don't remove from queue on fail, just leave it to expire. */ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *transid, Octstr *linkedid, char *vasid, Octstr *service_code, List *hdrs, MmsMsg *m, Octstr **error, List **errl, int *retry) { Octstr *ret = NULL; int mtype = mms_messagetype(m); int hstatus = HTTP_OK, tstatus = -1; List *xto = gwlist_create(); MSoapMsg_t *mreq = NULL, *mresp = NULL; List *rh = NULL, *ph = NULL; Octstr *body = NULL, *rbody = NULL, *url = NULL; Octstr *s; char *xvasid = vasid ? vasid : (mmc->default_vasid ? octstr_get_cstr(mmc->default_vasid) : NULL); mms_info(0, "MM7", mmc->id, "MMSBox: Send[soap] to MMSC[%s], msg type [%s], from %s, to %s", mmc->id ? octstr_get_cstr(mmc->id) : "", mms_message_type_to_cstr(mtype), octstr_get_cstr(from), octstr_get_cstr(to)); gwlist_append(xto, to); if ((mreq = mm7_mmsmsg_to_soap(m, (mmc == NULL || mmc->no_senderaddress == 0) ? from : NULL, xto, transid, service_code, linkedid, 1, octstr_get_cstr(mmc->vasp_id), xvasid, NULL, 0,/* UA N/A on this side. */ hdrs)) == NULL) { *error = octstr_format("Failed to convert Msg[%S] 2 SOAP message!", mms_message_type_to_string(mtype)); goto done1; } if (mm7_soapmsg_to_httpmsg(mreq, &mmc->ver, &rh, &body) < 0) { *error = octstr_format("Failed to convert SOAP message to HTTP Msg!"); goto done1; } if (hdrs) http_header_combine(rh, hdrs); /* If specified, then update and pass on. */ hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph,&rbody); if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { *error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status=[%d]!", mmc->mmsc_url, hstatus); goto done1; } if ((mresp = mm7_parse_soap(ph, rbody)) == NULL) { *error = octstr_format("Failed to parse MMSC[url=%S, id=%S] response!", mmc->mmsc_url, mmc->id); goto done1; } if (errl) { /* Pick up status stuff -- for DLR */ if (*errl == NULL) *errl = http_create_empty_headers(); if ((s = mm7_soap_header_value(mresp, octstr_imm("StatusText"))) != NULL) { http_header_add(*errl, "X-Mbuni-StatusText", octstr_get_cstr(s)); octstr_destroy(s); } if ((s = mm7_soap_header_value(mresp, octstr_imm("Details"))) != NULL) { http_header_add(*errl, "X-Mbuni-StatusDetails", octstr_get_cstr(s)); octstr_destroy(s); } } /* Now look at response code and use it to tell you what you want. */ if ((s = mm7_soap_header_value(mresp, octstr_imm("StatusCode"))) != NULL) { tstatus = atoi(octstr_get_cstr(s)); octstr_destroy(s); } else if ((s = mm7_soap_header_value(mresp, octstr_imm("faultstring"))) != NULL) { tstatus = atoi(octstr_get_cstr(s)); octstr_destroy(s); } else tstatus = MM7_SOAP_FORMAT_CORRUPT; if (!MM7_SOAP_STATUS_OK(tstatus) && tstatus != MM7_SOAP_COMMAND_REJECTED) { Octstr *detail = mm7_soap_header_value(mresp, octstr_imm("Details")); char *tmp = (char *)mms_soap_status_to_cstr(tstatus); if (detail == NULL) detail = mm7_soap_header_value(mresp, octstr_imm("faultcode")); ret = NULL; mms_info(0, "MM7", mmc->id, "Send to MMSC[%s], failed, code=[%d=>%s], detail=[%s]", mmc ? octstr_get_cstr(mmc->id) : "", tstatus, tmp ? tmp : "", detail ? octstr_get_cstr(detail) : ""); *error = octstr_format("Failed to deliver to MMC[url=%S, id=%S], status=[%d=>%s]!", mmc->mmsc_url, mmc->id, tstatus, tmp ? tmp : ""); octstr_destroy(detail); } else { ret = mm7_soap_header_value(mresp, octstr_imm("MessageID")); mms_info(0, "MM7", NULL, "Sent to MMC[%s], code=[%d=>%s], msgid=[%s]", octstr_get_cstr(mmc->id), tstatus, mms_soap_status_to_cstr(tstatus), ret ? octstr_get_cstr(ret) : "(none)"); } if (ret) mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); done1: *retry = (ret == NULL && (!MM7_SOAP_CLIENT_ERROR(tstatus) || tstatus < 0)); mm7_soap_destroy(mreq); mm7_soap_destroy(mresp); http_destroy_headers(rh); octstr_destroy(body); http_destroy_headers(ph); octstr_destroy(rbody); octstr_destroy(url); gwlist_destroy(xto, NULL); return ret; }
MmsEnvelope *mms_queue_create_envelope(Octstr *from, List *to, Octstr *subject, Octstr *fromproxy, Octstr *viaproxy, time_t senddate, time_t expirydate, Octstr *token, Octstr *vaspid, Octstr *vasid, Octstr *url1, Octstr *url2, List *hdrs, int dlr, Octstr *mmscname, MmsMsg *m, char *xqfname, char *src_interface, int extra_space, Octstr **binary_mms) { MmsEnvelope *e; Octstr *msgid = NULL, *ms = NULL, *r, *xfrom; int mtype = -1, i, n; if (m) { mtype = mms_messagetype(m); /* Get MsgID, Fixup if not there and needed. */ if ((msgid = mms_get_header_value(m, octstr_imm("Message-ID"))) == NULL && xqfname) { msgid = mms_make_msgid(xqfname, mmscname); if (mtype == MMS_MSGTYPE_SEND_REQ) mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid)); } ms = mms_tobinary(m); } xfrom = copy_and_clean_address(from); e = gw_malloc(extra_space + sizeof *e); /* Make envelope, clear it. */ memset(e, 0, sizeof *e); e->qfs_data = (void *)(e+1); /* pointer to data object for module. */ e->msgtype = mtype; e->from = xfrom; e->created = time(NULL); e->sendt = senddate; e->expiryt = expirydate ? expirydate : time(NULL) + DEFAULT_EXPIRE; e->lasttry = 0; e->attempts = 0; e->lastaccess = 0; e->fromproxy = fromproxy ? octstr_duplicate(fromproxy) : NULL; e->viaproxy = viaproxy ? octstr_duplicate(viaproxy) : NULL; e->subject = subject ? octstr_duplicate(subject) : NULL; e->to = gwlist_create(); e->msize = ms ? octstr_len(ms) : 0; e->msgId = msgid; e->token = token ? octstr_duplicate(token) : NULL; e->vaspid = vaspid ? octstr_duplicate(vaspid) : NULL; e->vasid = vasid ? octstr_duplicate(vasid) : NULL; e->url1 = url1 ? octstr_duplicate(url1) : NULL; e->url2 = url2 ? octstr_duplicate(url2) : NULL; e->hdrs = hdrs ? http_header_duplicate(hdrs) : NULL; e->dlr = dlr; strncpy(e->src_interface, src_interface ? src_interface : "", sizeof e->src_interface); if (xqfname) strncpy(e->xqfname, xqfname, sizeof e->xqfname); for (i = 0, n = to ? gwlist_len(to) : 0; i<n; i++) if ((r = gwlist_get(to, i)) != NULL && (r = copy_and_clean_address(r)) != NULL) { MmsEnvelopeTo *t = gw_malloc(sizeof *t); t->rcpt = r; t->process = 1; gwlist_append(e->to, t); } if (binary_mms) *binary_mms = ms; else octstr_destroy(ms); return e; }