/* * Get the mime ebXML message */ MIME *ebxml_getmessage (XML *xml, QUEUEROW *r) { MIME *msg, *payload, *soap; char *pid, *organization, buf[MAX_PATH]; int route; if ((route = cfg_route_index (xml, queue_field_get (r, "ROUTEINFO"))) < 0) return (NULL); organization = cfg_org (xml); pid = queue_field_get (r, "MESSAGEID"); if (pid != NULL) pid = strchr (pid, '-'); if (pid++ == NULL) { error ("Can't get PID from MESSAGEID\n"); return (NULL); } if (strcmp (queue_field_get (r, "ACTION"), "Ping")) { if ((payload = ebxml_getpayload (xml, r)) == NULL) return (NULL); } else payload = NULL; if ((soap = ebxml_getsoap (xml, r)) == NULL) { mime_free (payload); return (NULL); } debug ("building multipart mime message\n"); msg = mime_alloc (); sprintf (buf, "type=\"text/xml\"; start=\"ebxml-envelope@%s\";", organization); mime_setBoundary (msg, buf); sprintf (buf, "%s:%s", cfg_route (xml, route, "Host"), cfg_route (xml, route, "Port")); mime_setHeader (msg, "Host", buf, 99); mime_setHeader (msg, "Connection", "Close", 99); if (strcmp ("basic", cfg_route (xml, route, "Authentication.Type")) == 0) { basicauth_request (buf, cfg_route (xml, route, "Authentication.Id"), cfg_route (xml, route, "Authentication.Password")); pid = strchr (buf, ':'); *pid++ = 0; while (isspace (*pid)) pid++; mime_setHeader (msg, buf, pid, 99); } mime_setHeader (msg, "SOAPAction", "\"ebXML\"", 99); mime_setMultiPart (msg, soap); if (payload != NULL) mime_setMultiPart (msg, payload); debug ("Completed multipart soap message\n"); return (msg); }
/* * Get the mime header (soap) container */ MIME *ebxml_getsoap (XML *xml, QUEUEROW *r) { XML *soap; MIME *msg; char *ch, *pid, *partyid, *cpa, *organization, path[MAX_PATH], buf[MAX_PATH]; int route; debug ("getting soap container...\n"); organization = cfg_org (xml); pid = queue_field_get (r, "MESSAGEID"); if (pid != NULL) pid = strchr (pid, '-'); if (pid++ == NULL) { error ("Can't get PID from MESSAGEID\n"); return (NULL); } if ((route = cfg_route_index (xml, queue_field_get (r, "ROUTEINFO"))) < 0) return (NULL); debug ("getting soap template for pid=%s org=%s...\n", pid, organization); if ((soap = ebxml_template (xml, XSOAP)) == NULL) { error ("Can't get SOAP template\n"); return (NULL); } xml_set_text (soap, SOAPFROMPARTY, cfg_party (xml)); partyid = "Someone_else"; xml_set_text (soap, SOAPTOPARTY, partyid); cpa = cfg_route (xml, route, "Cpa"); xml_set_text (soap, SOAPCPAID, cpa); xml_set_text (soap, SOAPCONVERSEID, pid); xml_set_text (soap, SOAPSERVICE, queue_field_get (r, "SERVICE")); xml_set_text (soap, SOAPACTION, queue_field_get (r, "ACTION")); sprintf (buf, "%ld@%s", pid, organization); xml_set_text (soap, SOAPMESSAGEID, buf); queue_field_set (r, "MESSAGECREATIONTIME", ptime (NULL, buf)); xml_set_text (soap, SOAPDATATIME, buf); if (!strcmp (queue_field_get (r, "ACTION"), "Ping")) { xml_delete (soap, SOAPBODY); } else { sprintf (buf, "cid:%s@%s", queue_field_get (r, "PAYLOADFILE"), organization); debug ("set %s xlink:href=\"%s\"\n", SOAPMREF, buf); xml_set_attribute (soap, SOAPMREF, "xlink:href", buf); sprintf (buf, "%s.%s", r->queue->name, queue_field_get (r, "RECORDID")); xml_set_text (soap, SOAPDBRECID, buf); xml_set_text (soap, SOAPDBMESSID, queue_field_get (r, "MESSAGEID")); xml_set_text (soap, SOAPDBARGS, queue_field_get (r, "ARGUMENTS")); xml_set_text (soap, SOAPDBRECP, queue_field_get (r, "MESSAGERECIPIENT")); } debug ("building soap mime container...\n"); msg = mime_alloc (); mime_setHeader (msg, MIME_CONTENT, MIME_XML, 99); sprintf (buf, "<%s%s>", "ebxml-envelope@", organization); mime_setHeader (msg, MIME_CONTENTID, buf, 0); debug ("formatting soap xml...\n"); ch = xml_format (soap); debug ("soap envelope:\n%s\n", ch); xml_free (soap); mime_setBody (msg, ch, strlen (ch)); free (ch); debug ("returning soap message...\n"); return (msg); }
/* * parse a mime package */ MIME *mime_parse (char *buf) { char *ch, *p; int l, c; MIME *m, **n; char boundary[100]; /* * first find the header end */ if ((ch = strstr (buf, "\n\r\n")) != NULL) ch += 3; else if ((ch = strstr (buf, "\n\n")) != NULL) ch += 2; else { debug ("headers not found\n"); return (NULL); } c = *ch; *ch = 0; m = mime_alloc (); m->headers = (char *) malloc (ch - buf + 1); strcpy (m->headers, buf); *ch = c; debug ("headers:\n%s", m->headers); /* * next determine the size */ if ((m->len = mime_getLength (m)) == 0) { m->len = strlen (ch); mime_setLength (m, m->len); } debug ("len=%d\n", m->len); /* * copy in the body * if not a multipart then it's all body * we alloc an extra byte for the EOS */ if ((l = mime_getBoundary (m, boundary, 100)) < 1) { m->body = (unsigned char *) malloc (m->len + 1); memmove (m->body, ch, m->len); m->body[m->len] = 0; debug ("parse completed\n"); return (m); } /* * each part goes into the next chain */ n = &m->next; p = strstr (ch - 1, boundary); if (p > ch -1) { m->len = p - ch; c = *p; *p = 0; m->body = (unsigned char *) malloc (m->len + 1); memmove (m->body, ch, m->len + 1); } else m->len = 0; ch = p; while (1) { ch += l; /* bump past boundary marker */ debug ("checking end of boundry\n"); if ((ch[0] == ch[1]) && (ch[0] == '-')) break; /* find next one */ if (*ch++ == '\r') ch++; /* bump past CR LF */ if ((p = strstr (ch, boundary)) == NULL) { debug ("end boundary not found\n"); return (mime_free (m)); } c = *p; /* parse to it */ *p = 0; debug ("next part...\n"); if ((*n = mime_parse (ch)) == NULL) { debug ("next part did not parse\n"); return (mime_free (m)); } n = &(*n)->next; *p = c; ch = p; /* set up for next part */ } debug ("parse completed\n"); return (m); }