char* parse_fline(char* buffer, char* end, struct msg_start* fl) { if(end<=buffer) { /* make it throw error via parse_first_line() for consistency */ return parse_first_line(buffer, 0, fl); } return parse_first_line(buffer, (unsigned int)(end-buffer), fl); }
/* parse an option */ static int parse_option(char *line) { if (req.method==0) return parse_first_line(line); else return parse_header_line(line); }
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 HTTP::update_state() { if (state == 0 && text.find("\r\n") != std::string::npos) { state = FIRSTLINE; parse_first_line(); } if (state == FIRSTLINE && (body_start == 0 || body_start == std::string::npos)) { body_start = text.find("\r\n\r\n"); } if (state == FIRSTLINE && body_start != std::string::npos && body_start != 0) { state = HEADERS; body_start += 4; parse_headers(); } if (state >= HEADERS) { check_body(); } }
struct browser_request *parse_browser_request(char *message) { struct browser_request *request; request = malloc(sizeof(struct browser_request)); if(request == NULL) { perror("memory allocation Failure"); exit(EXIT_FAILURE); } char *line, *save_pointer; line = strtok_r(message, "\n\r", &save_pointer); parse_first_line(line, request); while((line = strtok_r(NULL, "\n\r", &save_pointer)) != NULL) { parse_request(line, request); } return request; }
static void process_data(struct http_client_request *req) { int bytes_to_commit = 0; while (req->state == EINPROGRESS) { char *parse_head = req->rcvbuf + req->parse_ptr; char *endline; int bytes_left; int line_size; bytes_left = req->read_ptr - req->parse_ptr; endline = memchr(parse_head, '\n', bytes_left); if (endline == NULL) { endline = memchr(parse_head, '\r', bytes_left); if (endline == NULL) { bytes_to_commit += bytes_left; break; } } line_size = endline - parse_head + 1; bytes_to_commit += line_size; req->parse_ptr += line_size; *endline = 0; if (parse_head != endline && endline[-1] == '\r') endline[-1] = 0; if (req->response_code == -1) parse_first_line(req, parse_head); else parse_header_line(req, parse_head); } commit(req, bytes_to_commit); }
/* returns 0 if ok, -1 for errors */ int parse_msg(char* const buf, const unsigned int len, struct sip_msg* const msg) { char *tmp; char* rest; struct msg_start *fl; int offset; hdr_flags_t flags; /* eat crlf from the beginning */ for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&& tmp-buf < len ; tmp++); offset=tmp-buf; fl=&(msg->first_line); rest=parse_first_line(tmp, len-offset, fl); offset+=rest-tmp; tmp=rest; switch(fl->type) { case SIP_INVALID: DBG("parse_msg: invalid message\n"); goto error; break; case SIP_REQUEST: DBG("SIP Request:\n"); DBG(" method: <%.*s>\n",fl->u.request.method.len, ZSW(fl->u.request.method.s)); DBG(" uri: <%.*s>\n",fl->u.request.uri.len, ZSW(fl->u.request.uri.s)); DBG(" version: <%.*s>\n",fl->u.request.version.len, ZSW(fl->u.request.version.s)); flags=HDR_VIA_F; break; case SIP_REPLY: DBG("SIP Reply (status):\n"); DBG(" version: <%.*s>\n",fl->u.reply.version.len, ZSW(fl->u.reply.version.s)); DBG(" status: <%.*s>\n", fl->u.reply.status.len, ZSW(fl->u.reply.status.s)); DBG(" reason: <%.*s>\n", fl->u.reply.reason.len, ZSW(fl->u.reply.reason.s)); /* flags=HDR_VIA | HDR_VIA2; */ /* we don't try to parse VIA2 for local messages; -Jiri */ flags=HDR_VIA_F; break; default: DBG("unknown type %d\n",fl->type); goto error; } msg->unparsed=tmp; /*find first Via: */ if (parse_headers(msg, flags, 0)==-1) goto error; #ifdef EXTRA_DEBUG /* dump parsed data */ if (msg->via1) { DBG("first via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>", msg->via1->name.len, ZSW(msg->via1->name.s), msg->via1->version.len, ZSW(msg->via1->version.s), msg->via1->transport.len, ZSW(msg->via1->transport.s), msg->via1->host.len, ZSW(msg->via1->host.s), msg->via1->port_str.len, ZSW(msg->via1->port_str.s), msg->via1->port); if (msg->via1->params.s) DBG(";<%.*s>", msg->via1->params.len, ZSW(msg->via1->params.s)); if (msg->via1->comment.s) DBG(" <%.*s>", msg->via1->comment.len, ZSW(msg->via1->comment.s)); DBG ("\n"); } if (msg->via2) { DBG("second via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>", msg->via2->name.len, ZSW(msg->via2->name.s), msg->via2->version.len, ZSW(msg->via2->version.s), msg->via2->transport.len, ZSW(msg->via2->transport.s), msg->via2->host.len, ZSW(msg->via2->host.s), msg->via2->port_str.len, ZSW(msg->via2->port_str.s), msg->via2->port); if (msg->via2->params.s) DBG(";<%.*s>", msg->via2->params.len, ZSW(msg->via2->params.s)); if (msg->via2->comment.s) DBG(" <%.*s>", msg->via2->comment.len, ZSW(msg->via2->comment.s)); DBG ("\n"); } #endif #ifdef EXTRA_DEBUG DBG("exiting parse_msg\n"); #endif return 0; error: /* more debugging, msg->orig is/should be null terminated*/ LOG(cfg_get(core, core_cfg, corelog), "ERROR: parse_msg: message=<%.*s>\n", (int)msg->len, ZSW(msg->buf)); return -1; }
bool jdk_http_request_header::parse_buffer( const char *buf, size_t len ) { // return true if an entire http request header is parsed or if a parsing error occurred. splitter.set_buf( (char *)buf, len ); jdk_str<4096> line; while( splitter.scan_for_line(&line) ) { // found a line! jdk_log( JDK_LOG_DEBUG4, "jdk_http_request_header::parsing line: '%s'", line.c_str() ); // ignore any initial blank lines. if( line.is_clear() && line_count==0 ) { continue; } ++line_count; // is this our final blank line? if( line.is_clear() && line_count>0 ) { // yup, we are done parsing. // if we have a valid host name then we have a valid request. if( !url.host.is_clear() ) { valid=true; } jdk_log( JDK_LOG_DEBUG4, "request_header parsed. buf_pos=%d, buf_len=%d", get_buf_pos(), splitter.get_buf_len() ); return true; } // is it our first line with the request? if( line_count==1 ) { if( !parse_first_line(line) ) { // error parsing first line. return true to stop parsing and is_valid() will be false. return true; } } else { // ok, it wasnt the first line. check for Host: and Port: lines if( line.nicmp( "Host:", 5 )==0 ) { if( url.host.is_clear() ) { // extract the value of this key jdk_str<300> tmp; tmp.cpy( line.c_str()+6 ); tmp.strip_begws(); tmp.strip_endws(); // is there a : specifying port as well? char *p = tmp.chr(':'); if( p ) { // yup, lets grab it and remove it from the string. url.port = strtol(p+1,0,10); *p='\0'; } url.host = tmp; } } else // how about a Port: line? if( line.nicmp( "Port:", 5 )==0 ) { url.port = strtol( line.c_str()+6, 0, 10 ); } else // we dont need to parse this line, just store it. { // extract the key, up to first colon key_t k; int pos = line.extract_token(0,&k,":"); // extract the value, from where key ended, skiping all white space value_t v; v.cpy( line.c_str() + pos + 1 ); // remove any trailing white space v.strip_begws(); v.strip_endws(); k.cat(':'); // add the colon back k.lower(); // lowercase the key since it is case insensitive // add the key and value to our map map.add( k, v ); } } } // return false so the caller knows to grab a new buffer // and call us again //jdk_log( JDK_LOG_DEBUG4, "jdk_http_request_header parsing not finished yet" ); return false; }
bool jdk_http_response_header::parse_buffer( const char *buf, size_t len ) { // return true if an entire http request header is parsed or if a parsing error occurred. splitter.set_buf( (char *)buf, len ); jdk_str<4096> line; while( splitter.scan_for_line(&line) ) { // found a line! jdk_log( JDK_LOG_DEBUG4, "jdk_http_response_header::parsing line: '%s'", line.c_str() ); // an initial blank line means the server is f****d and didnt respond with the proper http header. if( line.is_clear() && line_count==0 ) { valid=true; return true; } ++line_count; // is this our final blank line? if( line.is_clear() ) { // yup, we are done parsing. // if we have a valid http version and code then it is ok if( !http_version.is_clear() && http_response_code!=0 ) { valid=true; } return true; } // is the server f****d and did not include a blank line before putting a '<' from an html file? if( !line.is_clear() && line.get(0)=='<' ) { // yup! // yup, we are done parsing. valid=true; return true; } // is it our first line with the request? if( line_count==1 ) { if( !parse_first_line(line) ) { // error parsing first line. return true to stop parsing and is_valid() will be false. return true; } } else { // we dont need to parse this line, just store it. // extract the key, up to the first ':' key_t k; int pos = line.extract_token(0,&k,":"); k.lower(); // extract the value, from where key ended, skiping the colon and the white space value_t v; v.cpy( line.c_str() + pos + 1 ); // remove any trailing white space v.strip_begws(); v.strip_endws(); // put the colon back k.cat(':'); // add the key and value to our map map.add( k, v ); } } // return false so the caller knows to grab a new buffer // and call us again //jdk_log( JDK_LOG_DEBUG4, "jdk_http_response_header parsing not finished yet" ); return false; }
int parse_msg (struct sip_msg *msg, STRLIST * sender, STRLIST * recipient) { char *tmp; char *end; int length; int offset; char *header; char address[80] = { 0 }; char *body; int body_length; int off; int type; int evt; /* parse the data */ tmp = msg->buf; end = msg->buf + msg->len; /* strip the beginning space */ for (tmp; ((*tmp == '\n') || (*tmp == '\r')) && ((tmp - msg->buf) < length); tmp++); if (parse_first_line (&tmp, end, &(msg->type))) return 1; offset = tmp - msg->buf; do { switch (*tmp) { case 't': case 'T': { if (off = check ("TO", 2, tmp, end)) { if (LOG_PARSER) log_info ("Header To found in %u\n", tmp - msg->buf); offset += off; offset += find_end (tmp + off, end); /* find the user address */ tmp += off; if (get_address (tmp, address, msg->buf + offset - tmp, &(msg->sips))) { tmp = msg->buf + offset; break; } add_to_strlist2 (recipient, address, 0); if (LOG_PARSER) log_info ("The address is : %s\n", address); /* We only need one to header */ if (!msg->to) msg->to = parser_create_address (address, 0, msg->sips); tmp = msg->buf + offset; break; } } case 'f': case 'F': { if (off = check ("FROM", 4, tmp, end)) { if (LOG_PARSER) log_info ("Header From found in %u\n", tmp - msg->buf); offset += off; /* find the end of this header */ offset += find_end (tmp + off, end); /* find the user address */ tmp += off; if (get_address (tmp, address, msg->buf + offset - tmp, &(msg->sips))) { tmp = msg->buf + offset; break; } add_to_strlist2 (sender, address, 0); if (LOG_PARSER) log_info ("The address is : %s\n", address); /* We only require one from */ if (!msg->from) { /* copy from header to be used later */ msg->from = parser_create_address (address, 1, msg->sips); } tmp = msg->buf + offset; break; } } case 'v': case 'V': { if (off = check ("VIA", 3, tmp, end)) { if (LOG_PARSER) log_info ("Header Via found in %u\n", tmp - msg->buf); offset += off; /* find the end of this header */ offset += find_end (tmp + off, end); if (!msg->via1) msg->via1 = tmp; else if (!msg->via2) msg->via2 = tmp; tmp = msg->buf + offset; break; } } case 'e': case 'E': { if (off = check ("Event", 5, tmp, end)) { if (LOG_PARSER) log_info ("Header Event found in %u\n", tmp - msg->buf); offset += off; /* find the end of this header */ offset += find_end (tmp + off, end); tmp += off; msg->evt = parse_event (tmp, msg->buf + offset); tmp = msg->buf + offset; break; } } case 'r': case 'R': { if (off = check ("REQ", 3, tmp, end)) { if (LOG_PARSER) log_info ("Header Requester found in %u\n", tmp - msg->buf); offset += off; /* find the end of this header */ offset += find_end (tmp + off, end); /* find the user address */ tmp += off; for (tmp; (*tmp == ' ') && ((tmp) < end); tmp++); if (!msg->req) msg->req = parser_create_req (tmp); tmp = msg->buf + offset; break; } } default: { if (LOG_PARSER) log_info ("Other header found in %u\n", tmp - msg->buf); offset += find_end (tmp, end); tmp = msg->buf + offset; } } } while (not_out (&tmp) && tmp < end); msg->hdr_len = msg->hdr_len2 = tmp - msg->buf; /* We still have data left, it means body */ if (tmp < end) { msg->body_len = end - tmp; msg->body = tmp; } return 0; }
/* returns 0 if ok, -1 for errors */ int parse_msg(char* buf, unsigned int len, struct sip_msg* msg) { char *tmp; char* rest; struct msg_start *fl; int offset; hdr_flags_t flags; /* eat crlf from the beginning */ for (tmp=buf; (*tmp=='\n' || *tmp=='\r')&& (unsigned int)(tmp-buf) < len ; tmp++); offset=tmp-buf; fl=&(msg->first_line); rest=parse_first_line(tmp, len-offset, fl); offset+=rest-tmp; tmp=rest; switch(fl->type){ case SIP_INVALID: LM_DBG("invalid message\n"); /* if failed to parse the first line, we simply consider that the whole buffer was parsed, so that nothing is left to be parsed :) - this will do the trick and make "msg" struct acceptable for following parsing attempts */ msg->unparsed = msg->buf + msg->len; goto error; break; case SIP_REQUEST: LM_DBG("SIP Request:\n"); LM_DBG(" method: <%.*s>\n",fl->u.request.method.len, ZSW(fl->u.request.method.s)); LM_DBG(" uri: <%.*s>\n",fl->u.request.uri.len, ZSW(fl->u.request.uri.s)); LM_DBG(" version: <%.*s>\n",fl->u.request.version.len, ZSW(fl->u.request.version.s)); flags=HDR_VIA_F; break; case SIP_REPLY: LM_DBG("SIP Reply (status):\n"); LM_DBG(" version: <%.*s>\n",fl->u.reply.version.len, ZSW(fl->u.reply.version.s)); LM_DBG(" status: <%.*s>\n", fl->u.reply.status.len, ZSW(fl->u.reply.status.s)); LM_DBG(" reason: <%.*s>\n", fl->u.reply.reason.len, ZSW(fl->u.reply.reason.s)); flags=HDR_VIA_F; break; default: LM_DBG("unknown type %d\n",fl->type); goto error; } msg->unparsed=tmp; /*find first Via: */ if (parse_headers(msg, flags, 0)==-1) goto error; #ifdef EXTRA_DEBUG /* dump parsed data */ if (msg->via1){ LM_DBG(" first via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>", msg->via1->name.len, ZSW(msg->via1->name.s), msg->via1->version.len, ZSW(msg->via1->version.s), msg->via1->transport.len, ZSW(msg->via1->transport.s), msg->via1->host.len, ZSW(msg->via1->host.s), msg->via1->port_str.len, ZSW(msg->via1->port_str.s), msg->via1->port); if (msg->via1->params.s) LM_DBG(";<%.*s>", msg->via1->params.len, ZSW(msg->via1->params.s)); if (msg->via1->comment.s) LM_DBG(" <%.*s>", msg->via1->comment.len, ZSW(msg->via1->comment.s)); LM_DBG ("\n"); } if (msg->via2){ LM_DBG(" first via: <%.*s/%.*s/%.*s> <%.*s:%.*s(%d)>", msg->via2->name.len, ZSW(msg->via2->name.s), msg->via2->version.len, ZSW(msg->via2->version.s), msg->via2->transport.len, ZSW(msg->via2->transport.s), msg->via2->host.len, ZSW(msg->via2->host.s), msg->via2->port_str.len, ZSW(msg->via2->port_str.s), msg->via2->port); if (msg->via2->params.s) LM_DBG(";<%.*s>", msg->via2->params.len, ZSW(msg->via2->params.s)); if (msg->via2->comment.s) LM_DBG(" <%.*s>", msg->via2->comment.len, ZSW(msg->via2->comment.s)); LM_DBG ("\n"); } #endif #ifdef EXTRA_DEBUG LM_DBG("exiting\n"); #endif return 0; error: /* more debugging, msg->orig is/should be null terminated*/ LM_ERR("message=<%.*s>\n", (int)len, ZSW(buf)); return -1; }