static void http_thread(void *arg) { HTTPClient *client; Octstr *ip; Octstr *url; List *headers; Octstr *body; List *cgivars; Octstr *reply_body = octstr_create( "<?xml version=\"1.0\"?>\n" "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\"\n" " \"http://www.wapforum.org/DTD/wml_1.1.xml\">\n" "<wml>\n" "<card id=\"main\" title=\"Hello, world\" newcontext=\"true\">\n" " <p>Hello, world.</p>\n" "</card></wml>\n"); List *reply_headers = list_create(); int port; port = *(int *) arg; gw_free(arg); list_append(reply_headers, octstr_create("Content-Type: text/vnd.wap.wml")); for (;!dying;) { client = http_accept_request(port, &ip, &url, &headers, &body, &cgivars); if (client == NULL) break; http_send_reply(client, HTTP_OK, reply_headers, reply_body); http_destroy_headers(headers); octstr_destroy(ip); octstr_destroy(url); octstr_destroy(body); http_destroy_cgiargs(cgivars); } octstr_destroy(reply_body); http_destroy_headers(reply_headers); }
static void httpd_serve(HTTPClient *client, Octstr *ourl, List *headers, Octstr *body, List *cgivars) { Octstr *reply, *final_reply, *url; char *content_type; char *header, *footer; int status_type; int i; long pos; reply = final_reply = NULL; /* for compiler please */ url = octstr_duplicate(ourl); /* Set default reply format according to client * Accept: header */ if (http_type_accepted(headers, "text/vnd.wap.wml")) { status_type = BBSTATUS_WML; content_type = "text/vnd.wap.wml"; } else if (http_type_accepted(headers, "text/html")) { status_type = BBSTATUS_HTML; content_type = "text/html"; } else if (http_type_accepted(headers, "text/xml")) { status_type = BBSTATUS_XML; content_type = "text/xml"; } else { status_type = BBSTATUS_TEXT; content_type = "text/plain"; } /* kill '/cgi-bin' prefix */ pos = octstr_search(url, octstr_imm("/cgi-bin/"), 0); if (pos != -1) octstr_delete(url, pos, 9); else if (octstr_get_char(url, 0) == '/') octstr_delete(url, 0, 1); /* look for type and kill it */ pos = octstr_search_char(url, '.', 0); if (pos != -1) { Octstr *tmp = octstr_copy(url, pos+1, octstr_len(url) - pos - 1); octstr_delete(url, pos, octstr_len(url) - pos); if (octstr_str_compare(tmp, "txt") == 0) status_type = BBSTATUS_TEXT; else if (octstr_str_compare(tmp, "html") == 0) status_type = BBSTATUS_HTML; else if (octstr_str_compare(tmp, "xml") == 0) status_type = BBSTATUS_XML; else if (octstr_str_compare(tmp, "wml") == 0) status_type = BBSTATUS_WML; octstr_destroy(tmp); } for (i=0; httpd_commands[i].command != NULL; i++) { if (octstr_str_compare(url, httpd_commands[i].command) == 0) { reply = httpd_commands[i].function(cgivars, status_type); break; } } /* check if command found */ if (httpd_commands[i].command == NULL) { char *lb = bb_status_linebreak(status_type); reply = octstr_format("Unknown command `%S'.%sPossible commands are:%s", ourl, lb, lb); for (i=0; httpd_commands[i].command != NULL; i++) octstr_format_append(reply, "%s%s", httpd_commands[i].command, lb); } gw_assert(reply != NULL); if (status_type == BBSTATUS_HTML) { header = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n" "<html>\n<title>" GW_NAME "</title>\n<body>\n<p>"; footer = "</p>\n</body></html>\n"; content_type = "text/html"; } else if (status_type == BBSTATUS_WML) { header = "<?xml version=\"1.0\"?>\n" "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" " "\"http://www.wapforum.org/DTD/wml_1.1.xml\">\n" "\n<wml>\n <card>\n <p>"; footer = " </p>\n </card>\n</wml>\n"; content_type = "text/vnd.wap.wml"; } else if (status_type == BBSTATUS_XML) { header = "<?xml version=\"1.0\"?>\n" "<gateway>\n"; footer = "</gateway>\n"; } else { header = ""; footer = ""; content_type = "text/plain"; } final_reply = octstr_create(header); octstr_append(final_reply, reply); octstr_append_cstr(final_reply, footer); /* debug("bb.http", 0, "Result: '%s'", octstr_get_cstr(final_reply)); */ http_destroy_headers(headers); headers = list_create(); http_header_add(headers, "Content-Type", content_type); http_send_reply(client, HTTP_OK, headers, final_reply); octstr_destroy(url); octstr_destroy(ourl); octstr_destroy(body); octstr_destroy(reply); octstr_destroy(final_reply); http_destroy_headers(headers); http_destroy_cgiargs(cgivars); }
/* * Thread to listen to HTTP requests from SMSC entity */ static void httpsmsc_receiver(void *arg) { SMSCConn *conn = arg; ConnData *conndata = conn->data; HTTPClient *client; Octstr *ip, *url, *body; List *headers, *cgivars; /* Make sure we log into our own log-file if defined */ log_thread_to(conn->log_idx); while (conndata->shutdown == 0) { /* reset */ ip = url = body = NULL; headers = cgivars = NULL; /* XXX if conn->is_stopped, do not receive new messages.. */ client = http_accept_request(conndata->port, &ip, &url, &headers, &body, &cgivars); if (client == NULL) break; if (cgivars != NULL) { octstr_append_char(url, '?'); http_cgivar_dump_into(cgivars, url); } debug("smsc.http", 0, "HTTP[%s]: Got request `%s'", octstr_get_cstr(conn->id), octstr_get_cstr(url)); if (connect_denied(conndata->allow_ip, ip)) { info(0, "HTTP[%s]: Connection `%s' tried from denied " "host %s, ignored", octstr_get_cstr(conn->id), octstr_get_cstr(url), octstr_get_cstr(ip)); http_close_client(client); } else conndata->callbacks->receive_sms(conn, client, headers, body, cgivars); debug("smsc.http", 0, "HTTP[%s]: Destroying client information", octstr_get_cstr(conn->id)); octstr_destroy(url); octstr_destroy(ip); octstr_destroy(body); http_destroy_headers(headers); http_destroy_cgiargs(cgivars); } debug("smsc.http", 0, "HTTP[%s]: httpsmsc_receiver dying", octstr_get_cstr(conn->id)); conndata->shutdown = 1; http_close_port(conndata->port); /* unblock http_receive_result() if there are no open sends */ if (counter_value(conndata->open_sends) == 0) http_caller_signal_shutdown(conndata->http_ref); if (conndata->sender_thread != -1) { gwthread_wakeup(conndata->sender_thread); gwthread_join(conndata->sender_thread); } if (conndata->send_cb_thread != -1) { gwthread_wakeup(conndata->send_cb_thread); gwthread_join(conndata->send_cb_thread); } mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_DEAD; mutex_unlock(conn->flow_mutex); if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL) conndata->callbacks->destroy(conn); conn->data = NULL; conndata_destroy(conndata); bb_smscconn_killed(); }
static void client_thread(void *arg) { HTTPClient *client; Octstr *body, *url, *ip; List *headers, *resph, *cgivars; HTTPCGIVar *v; Octstr *reply_body, *reply_type; unsigned long n = 0; int status, i; while (run) { client = http_accept_request(port, &ip, &url, &headers, &body, &cgivars); n++; if (client == NULL) break; info(0, "Request for <%s> from <%s>", octstr_get_cstr(url), octstr_get_cstr(ip)); if (verbose) debug("test.http", 0, "CGI vars were"); /* * Don't use gwlist_extract() here, otherwise we don't have a chance * to re-use the cgivars later on. */ for (i = 0; i < gwlist_len(cgivars); i++) { if ((v = gwlist_get(cgivars, i)) != NULL && verbose) { octstr_dump(v->name, 0); octstr_dump(v->value, 0); } } if (arg == NULL) { reply_body = octstr_duplicate(reply_text); reply_type = octstr_create("Content-Type: text/plain; " "charset=\"UTF-8\""); } else { reply_body = octstr_duplicate(arg); reply_type = octstr_create("Content-Type: text/vnd.wap.wml"); } resph = gwlist_create(); gwlist_append(resph, reply_type); status = HTTP_OK; /* check for special URIs and handle those */ if (octstr_compare(url, octstr_imm("/quit")) == 0) { run = 0; } else if (octstr_compare(url, octstr_imm("/whitelist")) == 0) { octstr_destroy(reply_body); if (whitelist != NULL) { if (verbose) { debug("test.http.server", 0, "we send a white list"); octstr_dump(whitelist, 0); } reply_body = octstr_duplicate(whitelist); } else { reply_body = octstr_imm(""); } } else if (octstr_compare(url, octstr_imm("/blacklist")) == 0) { octstr_destroy(reply_body); if (blacklist != NULL) { if (verbose) { debug("test.http.server", 0, "we send a blacklist"); octstr_dump(blacklist, 0); } reply_body = octstr_duplicate(blacklist); } else { reply_body = octstr_imm(""); } } else if (octstr_compare(url, octstr_imm("/save")) == 0) { /* safe the body into a temporary file */ pid_t pid = getpid(); FILE *f = fopen(octstr_get_cstr(octstr_format("/tmp/body.%ld.%ld", pid, n)), "w"); octstr_print(f, body); fclose(f); } else if (octstr_compare(url, octstr_imm("/redirect/")) == 0) { /* provide us with a HTTP 302 redirection response * will return /redirect/<pid> for the location header * and will return /redirect/ if cgivar loop is set to allow looping */ Octstr *redirect_header, *scheme, *uri, *l; pid_t pid = getpid(); uri = ((l = http_cgi_variable(cgivars, "loop")) != NULL) ? octstr_format("%s?loop=%s", octstr_get_cstr(url), octstr_get_cstr(l)) : octstr_format("%s%ld", octstr_get_cstr(url), pid); octstr_destroy(reply_body); reply_body = octstr_imm("Here you got a redirection URL that you should follow."); scheme = ssl ? octstr_imm("https://") : octstr_imm("http://"); redirect_header = octstr_format("Location: %s%s%s", octstr_get_cstr(scheme), octstr_get_cstr(http_header_value(headers, octstr_imm("Host"))), octstr_get_cstr(uri)); gwlist_append(resph, redirect_header); status = HTTP_FOUND; /* will provide 302 */ octstr_destroy(uri); } else if (octstr_compare(url, octstr_imm("/mmsc")) == 0) { /* fake a M-Send.conf PDU which is using MMSEncapsulation as body */ pid_t pid = getpid(); FILE *f; gwlist_destroy(resph, octstr_destroy_item); octstr_destroy(reply_body); reply_type = octstr_create("Content-Type: application/vnd.wap.mms-message"); reply_body = octstr_create(""); octstr_append_from_hex(reply_body, "8c81" /* X-Mms-Message-Type: m-send-conf */ "98632d3862343300" /* X-Mms-Transaction-ID: c-8b43 */ "8d90" /* X-Mms-MMS-Version: 1.0 */ "9280" /* Response-status: Ok */ "8b313331373939353434393639383434313731323400" ); /* Message-Id: 13179954496984417124 */ resph = gwlist_create(); gwlist_append(resph, reply_type); /* safe the M-Send.req body into a temporary file */ f = fopen(octstr_get_cstr(octstr_format("/tmp/mms-body.%ld.%ld", pid, n)), "w"); octstr_print(f, body); fclose(f); } if (verbose) { debug("test.http", 0, "request headers were"); http_header_dump(headers); if (body != NULL) { debug("test.http", 0, "request body was"); octstr_dump(body, 0); } } if (extra_headers != NULL) http_header_combine(resph, extra_headers); /* return response to client */ http_send_reply(client, status, resph, reply_body); octstr_destroy(ip); octstr_destroy(url); octstr_destroy(body); octstr_destroy(reply_body); http_destroy_cgiargs(cgivars); gwlist_destroy(headers, octstr_destroy_item); gwlist_destroy(resph, octstr_destroy_item); } octstr_destroy(whitelist); octstr_destroy(blacklist); debug("test.http", 0, "Working thread 'client_thread' terminates"); http_close_all_ports(); }
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; }