static int receive_reply(HTTPCaller *caller) { void *id; int ret; Octstr *final_url; List *replyh; Octstr *replyb; Octstr *type; Octstr *charset; Octstr *os; id = http_receive_result(caller, &ret, &final_url, &replyh, &replyb); octstr_destroy(final_url); if (id == NULL || ret == -1) { error(0, "http GET failed"); gw_free(id); return -1; } debug("", 0, "Done with request %ld", *(long *) id); gw_free(id); http_header_get_content_type(replyh, &type, &charset); debug("", 0, "Content-type is <%s>, charset is <%s>", octstr_get_cstr(type), octstr_get_cstr(charset)); octstr_destroy(type); octstr_destroy(charset); if (verbose) debug("", 0, "Reply headers:"); while ((os = gwlist_extract_first(replyh)) != NULL) { if (verbose) octstr_dump(os, 1); octstr_destroy(os); } gwlist_destroy(replyh, NULL); if (verbose) { debug("", 0, "Reply body:"); octstr_dump(replyb, 1); } octstr_destroy(replyb); return 0; }
/* * Thread to handle finished sendings */ static void httpsmsc_send_cb(void *arg) { SMSCConn *conn = arg; ConnData *conndata = conn->data; Msg *msg; int status; List *headers; Octstr *final_url, *body; /* Make sure we log into our own log-file if defined */ log_thread_to(conn->log_idx); while(conndata->shutdown == 0 || counter_value(conndata->open_sends)) { msg = http_receive_result(conndata->http_ref, &status, &final_url, &headers, &body); if (msg == NULL) break; /* they told us to die, by unlocking */ counter_decrease(conndata->open_sends); if (conndata->max_pending_sends) semaphore_up(conndata->max_pending_sends); /* Handle various states here. */ /* request failed and we are not in shutdown mode */ if (status == -1 && conndata->shutdown == 0) { error(0, "HTTP[%s]: Couldn't connect to SMS center." "(retrying in %ld seconds) %ld.", octstr_get_cstr(conn->id), conn->reconnect_delay, counter_value(conndata->open_sends)); mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_RECONNECTING; mutex_unlock(conn->flow_mutex); /* XXX how should we know whether it's temp. error ?? */ bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL); /* * Just sleep reconnect delay and set conn to ACTIVE again; * otherwise if no pending request are here, we leave conn in * RECONNECTING state for ever and no routing (trials) take place. */ if (counter_value(conndata->open_sends) == 0) { gwthread_sleep(conn->reconnect_delay); /* and now enable routing again */ mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; time(&conn->connect_time); mutex_unlock(conn->flow_mutex); /* tell bearerbox core that we are connected again */ bb_smscconn_connected(conn); } continue; } /* request failed and we *are* in shutdown mode, drop the message */ else if (status == -1 && conndata->shutdown == 1) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); } /* request succeeded */ else { /* we received a response, so this link is considered online again */ if (conn->status != SMSCCONN_ACTIVE) { mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; time(&conn->connect_time); mutex_unlock(conn->flow_mutex); /* tell bearerbox core that we are connected again */ bb_smscconn_connected(conn); } conndata->callbacks->parse_reply(conn, msg, status, headers, body); } http_destroy_headers(headers); octstr_destroy(final_url); octstr_destroy(body); } debug("smsc.http", 0, "HTTP[%s]: httpsmsc_send_cb dying", octstr_get_cstr(conn->id)); conndata->shutdown = 1; if (counter_value(conndata->open_sends)) { warning(0, "HTTP[%s]: Shutdown while <%ld> requests are pending.", octstr_get_cstr(conn->id), counter_value(conndata->open_sends)); } }
/* * Try log in defined number of times, when got response 401 and authentica- * tion info is in headers. */ static int receive_push_reply(HTTPCaller *caller) { void *id; long *trid; int http_status, tries; List *reply_headers; Octstr *final_url, *auth_url, *reply_body, *os, *push_content, *auth_reply_body; WAPEvent *e; List *retry_headers; http_status = HTTP_UNAUTHORIZED; tries = 0; id = http_receive_result(caller, &http_status, &final_url, &reply_headers, &reply_body); if (id == NULL || http_status == -1 || final_url == NULL) { error(0, "push failed, no reason found"); goto push_failed; } while (use_headers && http_status == HTTP_UNAUTHORIZED && tries < retries) { debug("test.ppg", 0, "try number %d", tries); debug("test.ppg", 0, "authentication failure, get a challenge"); http_destroy_headers(reply_headers); push_content = push_content_create(); retry_headers = push_headers_create(octstr_len(push_content)); http_add_basic_auth(retry_headers, username, password); trid = gw_malloc(sizeof(long)); *trid = tries; http_start_request(caller, HTTP_METHOD_POST, final_url, retry_headers, push_content, 0, trid, NULL); debug("test.ppg ", 0, "TEST_PPG: doing response to %s", octstr_get_cstr(final_url)); octstr_destroy(push_content); http_destroy_headers(retry_headers); trid = http_receive_result(caller, &http_status, &auth_url, &reply_headers, &auth_reply_body); if (trid == NULL || http_status == -1 || auth_url == NULL) { error(0, "unable to send authorisation, no reason found"); goto push_failed; } debug("test.ppg", 0, "TEST_PPG: send authentication to %s, retry %ld", octstr_get_cstr(auth_url), *(long *) trid); gw_free(trid); octstr_destroy(auth_reply_body); octstr_destroy(auth_url); ++tries; } if (http_status == HTTP_NOT_FOUND) { error(0, "push failed, service not found"); goto push_failed; } if (http_status == HTTP_FORBIDDEN) { error(0, "push failed, service forbidden"); goto push_failed; } if (http_status == HTTP_UNAUTHORIZED) { if (use_headers) error(0, "tried %ld times, stopping", retries); else error(0, "push failed, authorisation failure"); goto push_failed; } debug("test.ppg", 0, "TEST_PPG: push %ld done: reply from, %s", *(long *) id, octstr_get_cstr(final_url)); gw_free(id); octstr_destroy(final_url); if (verbose) debug("test.ppg", 0, "TEST_PPG: reply headers were"); while ((os = gwlist_extract_first(reply_headers)) != NULL) { if (verbose) octstr_dump(os, 0); octstr_destroy(os); } if (verbose) { debug("test.ppg", 0, "TEST_PPG: reply body was"); octstr_dump(reply_body, 0); } e = NULL; if (pap_compile(reply_body, &e) < 0) { warning(0, "TEST_PPG: receive_push_reply: cannot compile pap message"); goto parse_error; } switch (e->type) { case Push_Response: debug("test.ppg", 0, "TEST_PPG: and type push response"); break; case Bad_Message_Response: debug("test.ppg", 0, "TEST_PPG: and type bad message response"); break; default: warning(0, "TEST_PPG: unknown event received from %s", octstr_get_cstr(final_url)); break; } octstr_destroy(reply_body); wap_event_destroy(e); http_destroy_headers(reply_headers); return 0; push_failed: gw_free(id); octstr_destroy(final_url); octstr_destroy(reply_body); http_destroy_headers(reply_headers); return -1; parse_error: octstr_destroy(reply_body); http_destroy_headers(reply_headers); wap_event_destroy(e); return -1; }