Пример #1
0
int		parse_header(int fd_src, t_parser *parser,
                             header_t *header, int *size)
{
  char		*line;

  reset_str(header->comment, COMMENT_LENGTH + 1);
  if ((line = get_next_size(fd_src, parser, size)) == NULL)
    return (1);
  if (parse_header_line(line, NAME_CMD_STRING, header->prog_name) == 1)
  {
    syntax_error(parser->line_nb);
    return (1);
  }
  free(line);
  header->prog_size = 0;
  if ((line = get_next_size(fd_src, parser, size)) == NULL)
    return (1);
  if (parse_header_line(line, COMMENT_CMD_STRING, header->comment) == 1)
  {
    syntax_error(parser->line_nb);
    return (1);
  }
  free(line);
  return (0);
}
Пример #2
0
http_status http_server::http_request_state::parse_message_line(const char* line)
// Parse the next line.
{
	VLOG("parse_message_line: '%s'\n", line);
	http_status status = HTTP_BAD_REQUEST;
	
	switch (m_request_state)
	{
	default:
	case PARSE_DONE:
		assert(0);
		break;
	case PARSE_START_LINE:
		status = parse_request_line(line);
		if (status < 400)
		{
			// Move on to the rest of the header.
			m_request_state = PARSE_HEADER;
		}
		break;
	case PARSE_HEADER:
		status = parse_header_line(line);
		break;
	}

	return status;
}
Пример #3
0
/* parse an option */
static int parse_option(char *line)
{
    if (req.method==0)
        return parse_first_line(line);
    else
        return parse_header_line(line);
}
Пример #4
0
static int finish_header_line(struct owfd_rtsp_decoder *dec, size_t rlen)
{
	char *line;
	size_t l;
	int r;

	l = rlen;
	line = shl_ring_copy(&dec->ring, &l);
	if (!line)
		return -ENOMEM;

	shl_ring_pull(&dec->ring, rlen);

	l = sanitize_header_line(dec, line, l);
	r = parse_header_line(dec, line);
	if (r < 0) {
		free(line);
		return r;
	}

	r = push_header_line(dec, line, l);
	if (r < 0) {
		free(line);
		return r;
	}

	return 0;
}
Пример #5
0
ssize_t req_parse(req_t *req, const char *data, size_t len)
{
    g_return_val_if_fail(req != NULL, -1);
    g_return_val_if_fail(data != NULL, -1);
    if (req_is_complete(req)) {
        g_warning("request already complete");
        return 0;
    }

    if (strlen(data) < len) {
        // we have a null somewhere in the string
        req->state = STATE_INVALID;
        return -1;
    }

    /* request not complete, data looks good.
     * time to split and parse. */

    ssize_t pos = 0;
    while (pos < len && !req_is_complete(req)) {
        ssize_t line_len;
        line_len = req_feed_line(req, data + pos, len - pos);
        if (line_len < 0) {
            // TODO better errors
            return -1;
        }
        pos += line_len;

        if (req->line_ready) {
            switch (req->state) {
                case STATE_INITIAL:
                    if (parse_request_line(req, req->buf, req->buf_size) < 0) {
                        return -1;
                    }
                    break;
                case STATE_IN_HEADER:
                    if (req->buf_size == 0) {
                        req->state = STATE_COMPLETE;
                    } else if (parse_header_line(req, req->buf, req->buf_size) < 0) {
                        return -1;
                    }
                    break;
                case STATE_COMPLETE:
                case STATE_INVALID:
                    g_return_val_if_reached(-1);
                    break;
            }
            g_free(req->buf);
            req->buf = NULL;
            req->buf_size = 0;
            req->line_ready = false;
        }
    }

    return pos;
}
Пример #6
0
/*
 * parse the first line (by first_line_fn) and headers
 * return -1 if the message is too long or non-standard
 */
static int
parse_general_http(struct parser *req, int (*first_line_fn)(struct parser *p))
{
        enum parse_state p_state = REQUEST_LINE;
        while (1) {
                if (req->parse_start >= req->parse_end) {
                        int ret = try_read(req, (req->recv_buf_end - req->parse_end));
                        if (ret == 0 || ret == -1) {  /* 0 means client closed */
                                syslog(LOG_INFO, "early close");
                                return -1;
                        }
                }

                char *p = line_end(req);
                if (!p) {
                        syslog(LOG_CRIT, "The headers are too long to handle");
                        return -1;
                }

                switch (p_state) {
                case REQUEST_LINE:
                        if (first_line_fn(req) == -1) {
                                syslog(LOG_CRIT, "The 1st line is bad");
                                return -1;
                        }
                        p_state = HEADER_LINES;
                        break;
                case HEADER_LINES:
                        if (p == req->parse_start) {  /* meeting 2 CRLF: end of headers */
                                req->parse_start += 2;
                                return 0;
                        }
                        if (parse_header_line(req) == -1) {
                                syslog(LOG_CRIT, "The header line is bad");
                                return -1;
                        }
                        break;
                }
        }
}
Пример #7
0
AW_Result
aw_session_run (AW_Session *sess)
{
	AW_MethodFunc func;
	AW_Char *line;
	AW_Result r;

	AW_ASSERT(sess);

	if (!(line = get_line(sess))) {
		return AW_ERR_SYNTAX;
	}

	if ((r = parse_request_line(sess, line)) != AW_OK)
		return r;

	while (1) {
		if (!(line = get_line(sess))) {
			return AW_ERR_SYNTAX;
		}

		if (line[0] == 0)
			break;

		if ((r = parse_header_line(sess, line)) != AW_OK)
			return r;
	}

	func = sess->serv->methods[sess->method];
	if (func) {
		r = func(sess, sess->method);
	} else {
		AW_ERROR(("do not support the method %d", sess->method));
		r = AW_ERR_NOTSUPP;
	}

	return r;
}
Пример #8
0
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);
}
Пример #9
0
/* Process each packet that passes the capture filter */
void parse_http_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pkt) {
        struct tm *pkt_time;
        char *header_line, *req_value;
        char saddr[INET6_ADDRSTRLEN], daddr[INET6_ADDRSTRLEN];
        char sport[PORTSTRLEN], dport[PORTSTRLEN];
        char ts[MAX_TIME_LEN];
        int is_request = 0, is_response = 0;
        unsigned int eth_type = 0, offset;

        const struct eth_header *eth;
        const struct ip_header *ip;
        const struct ip6_header *ip6;
        const struct tcp_header *tcp;
        const char *data;
        int size_ip, size_tcp, size_data, family;

        /* Check the ethernet type and insert a VLAN offset if necessary */
        eth = (struct eth_header *) pkt;
        eth_type = ntohs(eth->ether_type);
        if (eth_type == ETHER_TYPE_VLAN) {
                offset = link_offset + 4;
        } else {
                offset = link_offset;
        }

        offset += eth_skip_bits;

        /* Position pointers within packet stream and do sanity checks */
        ip = (struct ip_header *) (pkt + offset);
        ip6 = (struct ip6_header *) (pkt + offset);

        switch (IP_V(ip)) {
                case 4: family = AF_INET; break;
                case 6: family = AF_INET6; break;
                default: return;
        }

        if (family == AF_INET) {
                size_ip = IP_HL(ip) * 4;
                if (size_ip < 20) return;
                if (ip->ip_p != IPPROTO_TCP) return;
        } else { /* AF_INET6 */
                size_ip = sizeof(struct ip6_header);
                if (ip6->ip6_nh != IPPROTO_TCP)
                        size_ip = process_ip6_nh(pkt, size_ip, header->caplen, offset);
                if (size_ip < 40) return;
        }

        tcp = (struct tcp_header *) (pkt + offset + size_ip);
        size_tcp = TH_OFF(tcp) * 4;
        if (size_tcp < 20) return;

        data = (char *) (pkt + offset + size_ip + size_tcp);
        size_data = (header->caplen - (offset + size_ip + size_tcp));
        if (size_data <= 0) return;

        /* Check if we appear to have a valid request or response */
        if (is_request_method(data)) {
                is_request = 1;
        } else if (strncmp(data, HTTP_STRING, strlen(HTTP_STRING)) == 0) {
                is_response = 1;
        } else {
                return;
        }

        /* Copy packet data to editable buffer that was created in main() */
        if (size_data > BUFSIZ) size_data = BUFSIZ;
        memcpy(buf, data, size_data);
        buf[size_data] = '\0';

        /* Parse header line, bail if malformed */
        if ((header_line = parse_header_line(buf)) == NULL) return;

        if (is_request) {
                if (parse_client_request(header_line)) return;
        } else if (is_response) {
                if (parse_server_response(header_line)) return;
        }

        /* Iterate through request/entity header fields */
        while ((header_line = parse_header_line(NULL)) != NULL) {
                if ((req_value = strchr(header_line, ':')) == NULL) continue;
                *req_value++ = '\0';
                while (isspace(*req_value)) req_value++;

                insert_value(header_line, req_value);
        }

        /* Grab source/destination IP addresses */
        if (family == AF_INET) {
                inet_ntop(family, &ip->ip_src, saddr, sizeof(saddr));
                inet_ntop(family, &ip->ip_dst, daddr, sizeof(daddr));
        } else { /* AF_INET6 */
                inet_ntop(family, &ip6->ip_src, saddr, sizeof(saddr));
                inet_ntop(family, &ip6->ip_dst, daddr, sizeof(daddr));
        }
        insert_value("source-ip", saddr);
        insert_value("dest-ip", daddr);

        /* Grab source/destination ports */
        snprintf(sport, PORTSTRLEN, "%d", ntohs(tcp->th_sport));
        snprintf(dport, PORTSTRLEN, "%d", ntohs(tcp->th_dport));
        insert_value("source-port", sport);
        insert_value("dest-port", dport);

        /* Extract packet capture time */
        pkt_time = localtime((time_t *) &header->ts.tv_sec);
        strftime(ts, MAX_TIME_LEN, "%Y-%m-%d %H:%M:%S", pkt_time);
        insert_value("timestamp", ts);

        if (rate_stats) {
                update_host_stats(get_value("host"), header->ts.tv_sec);
                clear_values();
        } else {
                print_format_values();
        }

        if (dumpfile)
                pcap_dump((unsigned char *) dumpfile, header, pkt);

        num_parsed++;
        if (parse_count && (num_parsed >= parse_count))
                pcap_breakloop(pcap_hnd);

        return;
}
Пример #10
0
/* Process each packet that passes the capture filter */
void parse_http_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pkt) {
        struct tm *pkt_time;
        char *header_line, *req_value;
        char saddr[INET_ADDRSTRLEN], daddr[INET_ADDRSTRLEN];
        char sport[PORTSTRLEN], dport[PORTSTRLEN];
        char ts[MAX_TIME_LEN];
        int is_request = 0, is_response = 0;

        const struct ip_header *ip;
        const struct tcp_header *tcp;
        const char *data;
        int size_ip, size_tcp, size_data;

        /* Position pointers within packet stream and do sanity checks */
        ip = (struct ip_header *) (pkt + header_offset);
        size_ip = IP_HL(ip) * 4;
        if (size_ip < 20) return;
        if (ip->ip_p != IPPROTO_TCP) return;

        tcp = (struct tcp_header *) (pkt + header_offset + size_ip);
	size_tcp = TH_OFF(tcp) * 4;
	if (size_tcp < 20) return;

        data = (char *) (pkt + header_offset + size_ip + size_tcp);
        size_data = (header->caplen - (header_offset + size_ip + size_tcp));
        if (size_data <= 0) return;

        /* Check if we appear to have a valid request or response */
        if (is_request_method(data)) {
                is_request = 1;
        } else if (strncmp(data, HTTP_STRING, strlen(HTTP_STRING)) == 0) {
                is_response = 1;
        } else {
                return;
        }

        /* Copy packet data to editable buffer that was created in main() */
        if (size_data > BUFSIZ) size_data = BUFSIZ;
        strncpy(buf, data, size_data);
        buf[size_data] = '\0';

        /* Parse header line, bail if malformed */
        if ((header_line = parse_header_line(buf)) == NULL) return;

        if (is_request) {
                if (parse_client_request(header_line)) return;
        } else if (is_response) {
                if (parse_server_response(header_line)) return;
        }

        /* Iterate through request/entity header fields */
        while ((header_line = parse_header_line(NULL)) != NULL) {
                if ((req_value = strchr(header_line, ':')) == NULL) continue;
                *req_value++ = '\0';
                while (isspace(*req_value)) req_value++;

                insert_value(header_line, req_value);
        }

        /* Grab source/destination IP addresses */
        strncpy(saddr, (char *) inet_ntoa(ip->ip_src), INET_ADDRSTRLEN);
        strncpy(daddr, (char *) inet_ntoa(ip->ip_dst), INET_ADDRSTRLEN);
        insert_value("source-ip", saddr);
        insert_value("dest-ip", daddr);

        /* Grab source/destination ports */
        sprintf(sport, "%d", ntohs(tcp->th_sport));
        sprintf(dport, "%d", ntohs(tcp->th_dport));
        insert_value("source-port", sport);
        insert_value("dest-port", dport);

        /* Extract packet capture time */
        pkt_time = localtime((time_t *) &header->ts.tv_sec);
        strftime(ts, MAX_TIME_LEN, "%Y-%m-%d %H:%M:%S", pkt_time);
        insert_value("timestamp", ts);

        print_format_values();

        if (dumpfile)
                pcap_dump((unsigned char *) dumpfile, header, pkt);

        num_parsed++;
        if (parse_count && (num_parsed >= parse_count))
                pcap_breakloop(pcap_hnd);

        return;
}
Пример #11
0
void blizzard::http::process()
{
	bool quit = false;
	int res = 0;

	while (!quit)
	{
		switch (state_)
		{
		case sUndefined:
			want_read = true;
			want_write = false;
			state_ = sReadingHead;
			break;

		case sReadingHead:
			res = parse_title();
			if (res > 0)
			{
				state_ = sDone;
				quit = true;
			}
			else if (res < 0)
			{
				quit = true;
			}
			break;

		case sReadingHeaders:
			res = parse_header_line();
			if (res > 0)
			{
				state_ = sDone;
				quit = true;
			}
			else if (res < 0)
			{
				quit = true;
			}
			if (state_ == sReadyToHandle)
			{
				quit = true;
			}
			break;

		case sReadingPost:
			res = parse_post();
			if (res < 0)
			{
				quit = true;
			}
			break;

		case sReadyToHandle:
			commit();
			state_ = sWriting;
			break;

		case sWriting:
			want_write = true;
			res = write_data();
			if (res < 0)
			{
				quit = true;
			}
			break;

		case sDone:
			quit = true;
			break;

		default:
			break;
		}
	}
}
Пример #12
0
/* Just a lightweight http request processor */
void process_http(ape_socket *co, acetables *g_ape)
{
	ape_buffer *buffer = &co->buffer_in;
	http_state *http = co->parser.data;
	ape_parser *parser = &co->parser;
	
	char *data = buffer->data;
	int pos, read, p = 0;
	
	if (buffer->length == 0 || parser->ready == 1 || http->error == 1) {
		return;
	}

	/* 0 will be erased by the next read()'ing loop */
	data[buffer->length] = '\0';
	
	data = &data[http->pos];
	
	if (*data == '\0') {
		return;
	}
	
	/* Update the address of http->data and http->uri if buffer->data has changed (realloc) */
	if (http->buffer_addr != NULL && buffer->data != http->buffer_addr) {
		if (http->data != NULL) http->data = &buffer->data[(void *)http->data - (void *)http->buffer_addr];
		if (http->uri != NULL) http->uri = &buffer->data[(void *)http->uri - (void *)http->buffer_addr];
		http->buffer_addr = buffer->data;
	}
	
	switch(http->step) {
		case 0:
			pos = seof(data, '\n');
			if (pos == -1) {
				return;
			}
			
			switch(*(unsigned int *)data) {
#ifdef _LITTLE_ENDIAN
				case 0x20544547: /* GET + space */
#endif
#ifdef _BIG_ENDIAN
				case 0x47455420: /* GET + space */
#endif
					http->type = HTTP_GET;
					p = 4;
					break;
#ifdef _LITTLE_ENDIAN
				case 0x54534F50: /* POST */
#endif
#ifdef _BIG_ENDIAN
				case 0x504F5354: /* POST */
#endif
					http->type = HTTP_POST;
					p = 5;
					break;
				default:
					ape_log(APE_INFO, __FILE__, __LINE__, g_ape, "Invalid HTTP method in request: %s", data);
					http->error = 1;
					shutdown(co->fd, 2);
					return;
			}
			
			if (data[p] != '/') {
				http->error = 1;
				shutdown(co->fd, 2);
				return;
			} else {
				int i = p;
				while (p++) {
					switch(data[p]) {
						case ' ':
							http->pos = pos;
							http->step = 1;
							http->uri = &data[i];
							http->buffer_addr = buffer->data;
							data[p] = '\0';
							process_http(co, g_ape);
							return;
						case '?':
							if (data[p+1] != ' ' && data[p+1] != '\r' && data[p+1] != '\n') {
								http->buffer_addr = buffer->data;
								http->data = &data[p+1];
							}
							break;
						case '\r':
						case '\n':
						case '\0':
							ape_log(APE_INFO, __FILE__, __LINE__, g_ape, "Invalid line ending in request: %s", data);
							http->error = 1;
							shutdown(co->fd, 2);
							return;
					}
				}
			}
			break;
		case 1:
			pos = seof(data, '\n');
			if (pos == -1) {

				return;
			}
			if (pos == 1 || (pos == 2 && *data == '\r')) {
				if (http->type == HTTP_GET) {
					/* Ok, at this point we have a blank line. Ready for GET */
					buffer->data[http->pos] = '\0';
					urldecode(http->uri);
					parser->onready(parser, g_ape);
					parser->ready = -1;
					buffer->length = 0;
					return;
				} else if (http->type == HTTP_GET_WS) { /* WebSockets handshake needs to read 8 bytes */
					//urldecode(http->uri);
					http->contentlength = 8;
					http->buffer_addr = buffer->data;
					http->data = &buffer->data[http->pos+(pos)];
					http->step = 2;
				} else {
					/* Content-Length is mandatory in case of POST */
					if (http->contentlength == 0) {
						http->error = 1;
						shutdown(co->fd, 2);
						return;
					} else {
						http->buffer_addr = buffer->data; // save the addr
						http->data = &buffer->data[http->pos+(pos)];
						http->step = 2;
					}
				}
			} else {
				struct _http_header_line *hl;

				if ((hl = parse_header_line(data)) != NULL) {
					hl->next = http->hlines;
					http->hlines = hl;
					if (strcasecmp(hl->key.val, "host") == 0) {
						http->host = hl->value.val;
					}
				}
				if (http->type == HTTP_POST) {
					/* looking for content-length instruction */
					if (pos <= 25 && strncasecmp("content-length: ", data, 16) == 0) {
						int cl = atoi(&data[16]);

						/* Content-length can't be negative... */
						if (cl < 1 || cl > MAX_CONTENT_LENGTH) {
							http->error = 1;
							shutdown(co->fd, 2);
							return;
						}
						/* At this time we are ready to read "cl" bytes contents */
						http->contentlength = cl;

					}
				} else if (http->type == HTTP_GET) {
					if (strncasecmp("Sec-WebSocket-Key1: ", data, 20) == 0) {
						http->type = HTTP_GET_WS;
					}
				}
			}
			http->pos += pos;
			process_http(co, g_ape);
			break;
		case 2:
			read = buffer->length - http->pos; // data length
			http->pos += read;
			http->read += read;
			
			if (http->read >= http->contentlength) {

				parser->ready = 1;
				urldecode(http->uri);
				/* no more than content-length */
				buffer->data[http->pos - (http->read - http->contentlength)] = '\0';
				
				parser->onready(parser, g_ape);
				parser->ready = -1;
				buffer->length = 0;
			}
			break;
		default:
			break;
	}
}
Пример #13
0
static void kum_read_header( kum_file* kum, FILE* fp )
{
	char line[ MAX_LINE_SIZE ];
	char* key;
	char* value;
	char* s;

	while( fgets( line, MAX_LINE_SIZE, fp ) != NULL )
	{
		s = prepare_line( line, NULL );
		if( *s == '\0' )
		{
			continue;
		}

		
		if( strcmp( s, "BEGIN CHARMAP" ) == 0 )
		{
			break;
		}


		parse_header_line( line, &key, &value );
		
//		fprintf( stderr, "\'%s\' = \'%s\'\n", key, value );

		if( strcmp( "name", key ) == 0 )
		{
			strcpy( kum->name, value );
		}
		else if( strcmp( "type", key ) == 0 )
		{
			if( strcmp( value, "SBCS" ) == 0 )
			{
				kum->conv_type = KUM_SBCS;
			}
			else if( strcmp( value, "DBCS" ) == 0 )
			{
				kum->conv_type = KUM_DBCS;
			}
			else if( strcmp( value, "MBCS" ) == 0 )
			{
				kum->conv_type = KUM_MBCS;
			}
			else
			{
				fprintf( stderr, "kum error: invalid 'type' value\n." );
				exit( 1 );				
			}
		}
		else if( strcmp( "min_char_len", key ) == 0 )
		{
			char* end;
			kum->min_char_len = strtol( value, &end, 10 );
			if( kum->min_char_len <= 0 || *end != '\0' )
			{
				fprintf( stderr, "kum warning: invalid value of 'min_char_len'.\n" );
			}
		}
		else if( strcmp( "max_char_len", key ) == 0 )
		{
			char* end;
			kum->max_char_len = strtol( value, &end, 10 );
			if( kum->max_char_len <= 0 || *end != '\0' )
			{
				fprintf( stderr, "kum warning: invalid value of 'max_char_len'.\n" );
			}
		}
		else if( strcmp( "sub_char", key ) == 0 )
		{
			uint8_t bytes[ KUCONV_MAX_CHAR_LEN ];
			int8_t len;

			s = value;
			len = kum_parse_bytes( bytes, line, &s );
			if( len < 1 || len > 4 || *s != '\0' )
			{
				fprintf( stderr, "kum error: invalid value of 'sub_char'.\n" );
				exit( 1 );
			}
			
			kum->sub_char_len = len;
			memcpy( kum->sub_char, bytes, len );
		}
		else if( strcmp( "sub_char1", key ) == 0 )
		{
			uint8_t bytes[ KUCONV_MAX_CHAR_LEN ];
			int8_t len;

			s = value;
			len = kum_parse_bytes( bytes, line, &s );
			if( len != 1 || *s != '\0' )
			{
				fprintf( stderr, "kum error: invalid value of 'sub_char'.\n" );
				exit( 1 );
			}
			
			kum->sub_char1 = bytes[ 0 ];
		}
		else if( strcmp( "state", key ) == 0 )
		{
			switch( kum->conv_type )
			{
			case KUM_SBCS:
			case KUM_DBCS:
				kum->conv_type = KUM_MBCS;
				break;
			case KUM_MBCS:
				break;
			default:
				fprintf( stderr, "kum error: 'state' entry before the 'type'.\n");
				exit( 1 );
			}

			kum_add_state( &kum->states, value );
		}
		else
		{
			fprintf( stderr, "kum warning: unknown header value '%s'.\n", key );
		}
		
	}
}