And here is the patch itself =]
--
&Kalle Marjola ::: Development ::: Helsinki ::: Enpocket
? gwlib/gw_uuid_types.h
? test/test_boxc
? test/test_mime_multipart
? test/test_pcre
? test/test_prioqueue
? test/test_regex
? test/test_uuid
Index: gw/smsbox.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsbox.c,v
retrieving revision 1.252
diff -u -r1.252 smsbox.c
--- gw/smsbox.c 3 Sep 2004 12:42:33 -0000 1.252
+++ gw/smsbox.c 6 Oct 2004 12:34:55 -0000
@@ -130,6 +130,15 @@
int charset_processing (Octstr *charset, Octstr *text, int coding);
static long get_tag(Octstr *body, Octstr *tag, Octstr **value, long pos, int nostrip);
+/* for delayed HTTP answers.
+ * Dict key is uuid, value is HTTPClient pointer
+ * of open transaction
+ */
+
+static Dict *client_dict = NULL;
+static Octstr *stored_uuid_os = NULL; // horrible kludge!
+static List *sendsms_reply_hdrs = NULL;
+
/***********************************************************************
* Communication with the bearerbox.
*/
@@ -150,6 +159,60 @@
write_to_bearerbox(msg);
}
+/*
+ * Handle delayed reply to HTTP sendsms client, if any
+ */
+static void delayed_http_reply(Msg *msg)
+{
+ HTTPClient *client;
+ Octstr *os, *answer;
+ char id[UUID_STR_LEN + 1];
+ int status;
+
+ uuid_unparse(msg->ack.id, id);
+ os = octstr_create(id);
+ debug("sms.http", 0, "Got ACK (%d) of %s", msg->ack.nack, octstr_get_cstr(os));
+ client = dict_remove(client_dict, os);
+ if (client == NULL) {
+ warning(0, "No client? (multi-send?)");
+ octstr_destroy(os);
+ return;
+ }
+ /* XXX this should be fixed so that we really wait for DLR
+ * SMSC accept/deny before doing this - but that is far
+ * more slower, a bit more complex, and is done later on
+ */
+
+ switch (msg->ack.nack) {
+ case ack_success:
+ status = HTTP_ACCEPTED;
+ answer = octstr_create("0: Accepted for delivery");
+ break;
+ case ack_buffered:
+ status = HTTP_ACCEPTED;
+ answer = octstr_create("3: Queued for later delivery");
+ break;
+ case ack_failed:
+ status = HTTP_FORBIDDEN;
+ answer = octstr_create("Not routable. Do not try again.");
+ break;
+ case ack_failed_tmp:
+ status = HTTP_SERVICE_UNAVAILABLE;
+ answer = octstr_create("Temporal failure, try again later.");
+ break;
+ default:
+ error(0, "Strange reply from bearerbox!");
+ status = HTTP_SERVICE_UNAVAILABLE;
+ answer = octstr_create("Temporal failure, try again later.");
+ break;
+ }
+
+ http_send_reply(client, status, sendsms_reply_hdrs, answer);
+
+ octstr_destroy(answer);
+ octstr_destroy(os);
+}
+
/*
* Read an Msg from the bearerbox and send it to the proper receiver
@@ -189,11 +252,9 @@
total++;
list_produce(smsbox_requests, msg);
} else if (msg_type(msg) == ack) {
- /*
- * do nothing for now. Later we will handle this
- * gracefully...
- */
- msg_destroy(msg);
+
+ delayed_http_reply(msg);
+ msg_destroy(msg);
} else {
warning(0, "Received other message than sms/admin, ignoring!");
msg_destroy(msg);
@@ -2231,6 +2292,19 @@
udh == NULL ? ( text == NULL ? "" : octstr_get_cstr(text) ) : "<<
UDH >>");
}
}
+ /* XXX UGLY kludge, to be used in sendsms_thread */
+ if (stored_uuid_os == NULL) {
+ char id[UUID_STR_LEN + 1];
+
+ uuid_unparse(msg->sms.id, id);
+ stored_uuid_os = octstr_create(id);
+
+ debug("sms.http", 0, "Stored UUID %s", octstr_get_cstr(stored_uuid_os));
+
+ /* this octstr is then used to store the HTTP client into
+ * client_dict, if need to, in sendsms_thread */
+ }
+
msg_destroy(msg);
list_destroy(receiver, octstr_destroy_item);
list_destroy(allowed, octstr_destroy_item);
@@ -3018,17 +3092,12 @@
static void sendsms_thread(void *arg)
-{
+ {
HTTPClient *client;
Octstr *ip, *url, *body, *answer;
- List *hdrs, *args, *reply_hdrs;
+ List *hdrs, *args;
int status;
- reply_hdrs = http_create_empty_headers();
- http_header_add(reply_hdrs, "Content-type", "text/html");
- http_header_add(reply_hdrs, "Pragma", "no-cache");
- http_header_add(reply_hdrs, "Cache-Control", "no-cache");
-
for (;;) {
client = http_accept_request(sendsms_port, &ip, &url, &hdrs, &body,
&args);
@@ -3084,18 +3153,23 @@
debug("sms.http", 0, "Status: %d Answer: <%s>", status,
octstr_get_cstr(answer));
- octstr_destroy(ip);
- octstr_destroy(url);
- http_destroy_headers(hdrs);
- octstr_destroy(body);
- http_destroy_cgiargs(args);
-
- http_send_reply(client, status, reply_hdrs, answer);
+ octstr_destroy(ip);
+ octstr_destroy(url);
+ http_destroy_headers(hdrs);
+ octstr_destroy(body);
+ http_destroy_cgiargs(args);
- octstr_destroy(answer);
+ if (status != HTTP_ACCEPTED || stored_uuid_os == NULL)
+ http_send_reply(client, status, sendsms_reply_hdrs, answer);
+ else {
+ debug("sms.http", 0, "Delayed reply - wait for bearerbox");
+ dict_put(client_dict, stored_uuid_os, client);
+ octstr_destroy(stored_uuid_os);
+ stored_uuid_os = NULL;
+ }
+ octstr_destroy(answer);
}
- http_destroy_headers(reply_hdrs);
}
@@ -3411,6 +3485,13 @@
if (urltrans_add_cfg(translations, cfg) == -1)
panic(0, "urltrans_add_cfg failed");
+ client_dict = dict_create(32, NULL);
+ sendsms_reply_hdrs = http_create_empty_headers();
+ http_header_add(sendsms_reply_hdrs, "Content-type", "text/html");
+ http_header_add(sendsms_reply_hdrs, "Pragma", "no-cache");
+ http_header_add(sendsms_reply_hdrs, "Cache-Control", "no-cache");
+
+
caller = http_caller_create();
smsbox_requests = list_create();
smsbox_http_requests = list_create();
@@ -3474,6 +3555,9 @@
if (black_list_regex != NULL) gw_regex_destroy(black_list_regex);
cfg_destroy(cfg);
+ dict_destroy(client_dict); /* XXX is this right location? */
+ http_destroy_headers(sendsms_reply_hdrs); /* ditto */
+
/*
* Just sleep for a while to get bearerbox chance to restart.
* Otherwise we will fail while trying to connect to bearerbox!
Index: gwlib/http.h
===================================================================
RCS file: /home/cvs/gateway/gwlib/http.h,v
retrieving revision 1.63
diff -u -r1.63 http.h
--- gwlib/http.h 22 Jan 2004 14:08:25 -0000 1.63
+++ gwlib/http.h 6 Oct 2004 12:34:55 -0000
@@ -158,7 +158,8 @@
HTTP_UNSUPPORTED_MEDIA_TYPE = 415,
HTTP_INTERNAL_SERVER_ERROR = 500,
HTTP_NOT_IMPLEMENTED = 501,
- HTTP_BAD_GATEWAY = 502
+ HTTP_BAD_GATEWAY = 502,
+ HTTP_SERVICE_UNAVAILABLE = 503
};
/*