/* * Add push flag into push headers. Push flag is defined in ota, p. 17-18. * If there is no flags set, no Push-Flag header is added. */ static List *add_push_flag(WAPEvent *e) { int push_flag, trusted, authenticated, last; Octstr *buf; List *headers; flags_assert(e); if (e->type == Po_Unit_Push_Req) { trusted = e->u.Po_Unit_Push_Req.trusted << 1; authenticated = e->u.Po_Unit_Push_Req.authenticated; last = e->u.Po_Unit_Push_Req.last << 2; headers = http_header_duplicate(e->u.Po_Unit_Push_Req.push_headers); } else if (e->type == Po_Push_Req) { trusted = e->u.Po_Push_Req.trusted << 1; authenticated = e->u.Po_Push_Req.authenticated; last = e->u.Po_Push_Req.last << 2; headers = http_header_duplicate(e->u.Po_Push_Req.push_headers); } else if (e->type == Po_ConfirmedPush_Req) { trusted = e->u.Po_ConfirmedPush_Req.trusted << 1; authenticated = e->u.Po_ConfirmedPush_Req.authenticated; last = e->u.Po_ConfirmedPush_Req.last << 2; headers = http_header_duplicate( e->u.Po_ConfirmedPush_Req.push_headers); } else { debug("wap.ota", 0, "OTA: no push flag when the event is: \n"); wap_event_dump(e); return NULL; } push_flag = 0; push_flag = push_flag | authenticated | trusted | last; if (push_flag) { buf = octstr_format("%d", push_flag); http_header_add(headers, "Push-Flag", octstr_get_cstr(buf)); octstr_destroy(buf); } return headers; }
/* Replace top-level MIME headers: Old ones removed completetly */ void mime_replace_headers(MIMEEntity *e, List *headers) { gw_assert(e != NULL); gw_assert(headers != NULL); http_destroy_headers(e->headers); e->headers = http_header_duplicate(headers); e->start = NULL; /* clear it, since header change means it could have changed.*/ }
static WAPEvent *indicate_confirmedpush(WSPPushClientMachine *cpm, Octstr *push_body) { WAPEvent *e; e = wap_event_create(S_ConfirmedPush_Ind); e->u.S_ConfirmedPush_Ind.client_push_id = cpm->client_push_id; e->u.S_ConfirmedPush_Ind.push_headers = http_header_duplicate(cpm->push_headers); e->u.S_ConfirmedPush_Ind.push_body = octstr_duplicate(push_body); return e; }
List *mime_entity_headers(MIMEEntity *m) { List *headers; gw_assert(m != NULL && m->headers != NULL); /* Need a fixup before hand over. */ if (mime_entity_num_parts(m) > 0) fix_boundary_element(m->headers, NULL); headers = http_header_duplicate(m->headers); return headers; }
static void make_session_request(WAPEvent *e) { WAPEvent *wsp_event; List *appid_headers, *push_headers; gw_assert(e->type == Pom_SessionRequest_Req); push_headers = e->u.Pom_SessionRequest_Req.push_headers; check_session_request_headers(push_headers); wsp_event = wap_event_create(S_Unit_Push_Req); wsp_event->u.S_Unit_Push_Req.address_type = e->u.Pom_SessionRequest_Req.address_type; if (e->u.Pom_SessionRequest_Req.smsc_id != NULL) wsp_event->u.S_Unit_Push_Req.smsc_id = octstr_duplicate(e->u.Pom_SessionRequest_Req.smsc_id); else wsp_event->u.S_Unit_Push_Req.smsc_id = NULL; if (e->u.Pom_SessionRequest_Req.dlr_url != NULL) wsp_event->u.S_Unit_Push_Req.dlr_url = octstr_duplicate(e->u.Pom_SessionRequest_Req.dlr_url); else wsp_event->u.S_Unit_Push_Req.dlr_url = NULL; wsp_event->u.S_Unit_Push_Req.dlr_mask = e->u.Pom_SessionRequest_Req.dlr_mask; if (e->u.Pom_SessionRequest_Req.smsbox_id != NULL) wsp_event->u.S_Unit_Push_Req.smsbox_id = octstr_duplicate(e->u.Pom_SessionRequest_Req.smsbox_id); else wsp_event->u.S_Unit_Push_Req.smsbox_id = NULL; wsp_event->u.S_Unit_Push_Req.service_name = octstr_duplicate(e->u.Pom_SessionRequest_Req.service_name); wsp_event->u.S_Unit_Push_Req.push_id = e->u.Pom_SessionRequest_Req.push_id; wsp_event->u.S_Unit_Push_Req.addr_tuple = wap_addr_tuple_duplicate(e->u.Pom_SessionRequest_Req.addr_tuple); wsp_event->u.S_Unit_Push_Req.push_headers = http_header_duplicate(push_headers); appid_headers = http_header_find_all(push_headers, "X-WAP-Application-Id"); wsp_event->u.S_Unit_Push_Req.push_body = pack_sia(appid_headers); debug("wap.push.ota", 0, "OTA: making a connectionless session request for" " creating a session"); dispatch_to_wsp_unit(wsp_event); }
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; }
/* * This routine is used for mime_[http|octstr]_to_entity() in order to * reduce code duplication. Basically the only difference is how the headers * are parsed or passed to the resulting MIMEEntity representation. */ static MIMEEntity *mime_something_to_entity(Octstr *mime, List *headers) { MIMEEntity *e; ParseContext *context; Octstr *value, *boundary, *start; int len = 0; debug("mime.parse",0,"mime_something_to_entity"); octstr_dump(mime,0); gw_assert(mime != NULL); value = boundary = start = NULL; context = parse_context_create(mime); e = mime_entity_create(); /* parse the headers up to the body. If we have headers already passed * from our caller, then duplicate them and continue */ if (headers != NULL) { /* we have some headers to duplicate, first ensure we destroy * the list from the previous creation inside mime_entity_create() */ http_destroy_headers(e->headers); e->headers = http_header_duplicate(headers); } else { /* parse the headers out of the mime block */ if ((read_mime_headers(context, e->headers) != 0) || e->headers == NULL) { debug("mime.parse",0,"Failed to read MIME headers in Octstr block:"); octstr_dump(mime, 0); mime_entity_destroy(e); parse_context_destroy(context); return NULL; } } /* * Now check if the body is a multipart. This is indicated by an 'boundary' * parameter in the 'Content-Type' value. If yes, call ourself for the * multipart entities after parsing them. */ value = http_header_value(e->headers, octstr_imm("Content-Type")); debug("mime.parse",0,"value: %s", octstr_get_cstr(value)); boundary = http_get_header_parameter(value, octstr_imm("boundary")); debug("mime.parse",0,"boundary: %s", octstr_get_cstr(boundary)); start = get_start_param(value); /* Beware that we need *unquoted* strings to compare against in the * following parsing sections. */ if (boundary && (len = octstr_len(boundary)) > 0 && octstr_get_char(boundary, 0) == '"' && octstr_get_char(boundary, len-1) == '"') { octstr_delete(boundary, 0, 1); octstr_delete(boundary, len-2, 1); } debug("mime.parse",0, "Boundrary is %s", octstr_get_cstr(boundary)); if (boundary != NULL) { /* we have a multipart block as body, parse the boundary blocks */ Octstr *entity, *seperator, *os; /* loop by all boundary blocks we have in the body */ seperator = octstr_create("--"); octstr_append(seperator, boundary); while ((entity = parse_get_seperated_block(context, seperator)) != NULL) { MIMEEntity *m; int del2 = 0; /* we have still linefeeds at the beginning and end that we * need to remove, these are from the separator. * We check if it is LF only or CRLF! */ del2 = (octstr_get_char(entity, 0) == '\r'); if (del2) octstr_delete(entity, 0, 2); else octstr_delete(entity, 0, 1); /* we assume the same mechanism applies to beginning and end -- * seems reasonable! */ if (del2) octstr_delete(entity, octstr_len(entity) - 2, 2); else octstr_delete(entity, octstr_len(entity) - 1, 1); debug("mime.parse",0,"MIME multipart: Parsing entity:"); octstr_dump(entity, 0); /* call ourself for this MIME entity and inject to list */ if ((m = mime_octstr_to_entity(entity))) { gwlist_append(e->multiparts, m); /* check if this entity is our start entity (in terms of related) * and set our start pointer to it */ if (cid_matches(m->headers, start)) { /* set only if none has been set before */ e->start = (e->start == NULL) ? m : e->start; } } octstr_destroy(entity); } /* ok, we parsed all blocks, we expect to see now the end boundary */ octstr_append_cstr(seperator, "--"); os = parse_get_line(context); if (os != NULL && octstr_compare(os, seperator) != 0) { debug("mime.parse",0,"Failed to see end boundary, parsed line is '%s'.", octstr_get_cstr(os)); } octstr_destroy(seperator); octstr_destroy(os); } else { /* we don't have boundaries, so this is no multipart block, * pass the body to the MIME entity. */ e->body = parse_get_rest(context); } parse_context_destroy(context); octstr_destroy(value); octstr_destroy(boundary); octstr_destroy(start); return e; }
Octstr *mime_entity_to_octstr(MIMEEntity *m) { Octstr *mime, *boundary = NULL; List *headers; long i; gw_assert(m != NULL && m->headers != NULL); mime = octstr_create(""); /* * First of all check if we have further MIME entity dependencies, * which means we have further MIMEEntities in our m->multiparts * list. If no, then add headers and body and return. This is the * easy case. Otherwise we have to loop inside our entities. */ if (gwlist_len(m->multiparts) == 0) { for (i = 0; i < gwlist_len(m->headers); i++) { octstr_append(mime, gwlist_get(m->headers, i)); octstr_append(mime, octstr_imm("\r\n")); } octstr_append(mime, octstr_imm("\r\n")); if (m->body != NULL) octstr_append(mime, m->body); goto finished; } /* This call ensures boundary exists, and returns it */ fix_boundary_element(m->headers, &boundary); headers = http_header_duplicate(m->headers); /* headers */ for (i = 0; i < gwlist_len(headers); i++) { octstr_append(mime, gwlist_get(headers, i)); octstr_append(mime, octstr_imm("\r\n")); } http_destroy_headers(headers); octstr_append(mime, octstr_imm("\r\n")); /* Mark end of headers. */ /* loop through all MIME multipart entities of this entity */ for (i = 0; i < gwlist_len(m->multiparts); i++) { MIMEEntity *e = gwlist_get(m->multiparts, i); Octstr *body; octstr_append(mime, octstr_imm("\r\n--")); octstr_append(mime, boundary); octstr_append(mime, octstr_imm("\r\n")); /* call ourself to produce the MIME entity body */ body = mime_entity_to_octstr(e); octstr_append(mime, body); octstr_destroy(body); } octstr_append(mime, octstr_imm("\r\n--")); octstr_append(mime, boundary); octstr_append(mime, octstr_imm("--\r\n")); octstr_destroy(boundary); finished: return mime; }