int tcp_http11_continue(struct tcp_connection *c) { struct dest_info dst; char *p; struct msg_start fline; int ret; str msg; ret = 0; msg.s = c->req.start; msg.len = c->req.pos - c->req.start; #ifdef READ_MSRP /* skip if MSRP message */ if(c->req.flags&F_TCP_REQ_MSRP_FRAME) return 0; #endif p = parse_first_line(msg.s, msg.len, &fline); if(p==NULL) return 0; if(fline.type!=SIP_REQUEST) return 0; /* check if http request */ if(fline.u.request.version.len < HTTP_VERSION_LEN || strncasecmp(fline.u.request.version.s, HTTP_VERSION, HTTP_VERSION_LEN)) return 0; /* check for Expect header */ if(strfindcasestrz(&msg, "Expect: 100-continue")!=NULL) { init_dst_from_rcv(&dst, &c->rcv); if (tcp_send(&dst, 0, HTTP11CONTINUE, HTTP11CONTINUE_LEN) < 0) { LM_ERR("HTTP/1.1 continue failed\n"); } } /* check for Transfer-Encoding header */ if(strfindcasestrz(&msg, "Transfer-Encoding: chunked")!=NULL) { c->req.flags |= F_TCP_REQ_BCHUNKED; ret = 1; } /* check for HTTP Via header * - HTTP Via format is different that SIP Via * - workaround: replace with Hia to be ignored by SIP parser */ if((p=strfindcasestrz(&msg, "\nVia:"))!=NULL) { p++; *p = 'H'; LM_DBG("replaced HTTP Via with Hia [[\n%.*s]]\n", msg.len, msg.s); } return ret; }
void async_http_cb(struct http_m_reply *reply, void *param) { async_query_t *aq; cfg_action_t *act; unsigned int tindex; unsigned int tlabel; struct cell *t = NULL; char *p; sip_msg_t *fmsg; if (reply->result != NULL) { LM_DBG("query result = %.*s [%d]\n", reply->result->len, reply->result->s, reply->result->len); } /* clean process-local result variables */ ah_error.s = NULL; ah_error.len = 0; memset(ah_reply, 0, sizeof(struct sip_msg)); /* set process-local result variables */ if (reply->result == NULL) { /* error */ ah_error.s = reply->error; ah_error.len = strlen(ah_error.s); } else { /* success */ /* check for HTTP Via header * - HTTP Via format is different that SIP Via * - workaround: replace with Hia to be ignored by SIP parser */ if((p=strfindcasestrz(reply->result, "\nVia:"))!=NULL) { p++; *p = 'H'; LM_DBG("replaced HTTP Via with Hia [[\n%.*s]]\n", reply->result->len, reply->result->s); } ah_reply->buf = reply->result->s; ah_reply->len = reply->result->len; if (parse_msg(reply->result->s, reply->result->len, ah_reply) != 0) { LM_DBG("failed to parse the http_reply\n"); } else { LM_DBG("successfully parsed http reply %p\n", ah_reply); } } aq = param; strncpy(q_id, aq->id, strlen(aq->id)); act = (cfg_action_t*)aq->param; if (aq->query_params.suspend_transaction) { tindex = aq->tindex; tlabel = aq->tlabel; if (tmb.t_lookup_ident(&t, tindex, tlabel) < 0) { LM_ERR("transaction not found %d:%d\n", tindex, tlabel); LM_DBG("freeing query %p\n", aq); free_async_query(aq); return; } // we bring the list of AVPs of the transaction to the current context set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from); set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to); set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from); set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to); set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from); set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to); if (t) tmb.unref_cell(t); LM_DBG("resuming transaction (%d:%d)\n", tindex, tlabel); if(act!=NULL) tmb.t_continue(tindex, tlabel, act); } else { fmsg = faked_msg_next(); if (run_top_route(act, fmsg, 0)<0) LM_ERR("failure inside run_top_route\n"); } free_sip_msg(ah_reply); free_async_query(aq); return; }