Beispiel #1
0
	void HttpTaskRunnable::parseRequest(const QByteArray& data)
	{
		http_parser_settings settings;
		memset(&settings, 0, sizeof(settings));
		settings.on_url = uriHandler;
		settings.on_header_field = headerFieldHandler;
		settings.on_header_value = headerFieldValueHandler;
		settings.on_headers_complete = headersCompleteHandler;
		settings.on_body = bodyHandler;
		settings.on_message_complete = messageCompleteHandler;

		http_parser parser;
		memset(&parser, 0, sizeof(parser));

		http_parser_init(&parser, HTTP_REQUEST);
		parser.data = this;

		http_parser_execute(&parser, &settings, data.constData(), data.size());
	}
Beispiel #2
0
	bool RESTfulParser::IsParsable(const char* data, size_t length)
	{
        const char HeaderEnd[] = "\r\n\r\n";
        const size_t HeaderLength = strlen(HeaderEnd);
		
        if(this->request.hasHeader == false)
        {
            for(size_t i = 0 ; i < length; ++i)
            {
                if(data[i] == HeaderEnd[0])
                {
                    size_t headerPos = 1;
                    for(; headerPos < HeaderLength && i + headerPos < length; ++headerPos)
                    {
                        if(data[i + headerPos] != HeaderEnd[headerPos])
                        {
                            break;
                        }
                    }

                    if(headerPos == HeaderLength)
                    {
                        this->request.bodyOffset = i + HeaderLength;

                        size_t parsedLength = 
                            http_parser_execute(&this->parser, &this->settings, data, this->request.bodyOffset);
                        
                        this->request.hasHeader = true;
                    }
                }
            }

            if(this->request.hasHeader == false)
            {
                return false;
            }
        }
        if( this->request.bodyOffset + this->request.bodySize > length)
        {
            return false;
        }
		return true;
	}
Beispiel #3
0
int http_handle(struct data_node *p_node)
{
	http_parser *hp = &p_node->http_info.hp;
	struct http_status *p_stat = &p_node->http_info.hs;
	if ((p_stat->dosize == 0) || (p_stat->step == 0)){
		http_parser_init(hp, HTTP_REQUEST);
	}
	int todo = (p_node->recv.get_size - p_stat->dosize);
	// printf("recv.get_size %d  dosize %d\n", p_node->recv.get_size, p_stat->dosize);
	int done = http_parser_execute(hp,
			&settings,
			(p_node->recv.buf_addr + p_stat->dosize),
			todo);
	p_stat->step++;
	if (p_stat->over) {
		p_stat->dosize = 0;
	}else{
		p_stat->dosize += done;
	}
	// x_printf("%d of %d\n", done, todo);

	if (hp->upgrade) {
		/* handle new protocol  处理新协议*/
		//TODO
		// x_printf("upgrade!\n");
		return FALSE;
	} else {
		if (done == todo) {
			return (p_stat->over);
		}else{
			/*it's error request,change to over and shoud broken socket*/
			/* Handle error. Usually just close the connection.  处理错误,通常是关闭这个连接*/
			p_stat->err = HTTP_PARSER_ERRNO(hp);
			if (HPE_OK != p_stat->err) {
				fprintf(stderr, "\n*** server expected %s, but saw %s ***\n%s\n",
						http_errno_name(HPE_OK), http_errno_name(p_stat->err), (p_node->recv.buf_addr + p_stat->dosize));
			}
			p_stat->dosize = 0;
			return TRUE;
		}
	}
}
Beispiel #4
0
ssize_t HttpMessage::ParseFromArray(const char *data, const size_t length) {
    if (Completed()) {
        if (length == 0) {
            return 0;
        }
        LOG(ERROR) << "Append data(len=" << length
                   << ") to already-completed message";
        return -1;
    }
    const size_t nprocessed =
        http_parser_execute(&_parser, &g_parser_settings, data, length);
    if (_parser.http_errno != 0) {
        // May try HTTP on other formats, failure is norm.
        RPC_VLOG << "Fail to parse http message, parser=" << _parser
                 << ", buf=`" << butil::StringPiece(data, length) << '\'';
        return -1;
    } 
    _parsed_length += nprocessed;
    return nprocessed;
}
Beispiel #5
0
static mrb_value
mrb_http_parser_parse_request(mrb_state *mrb, mrb_value self)
{
  mrb_value arg_data = mrb_nil_value();
  mrb_value value_context;
  mrb_http_parser_context* context;
  mrb_value b = mrb_nil_value();

  value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "context"));
  Data_Get_Struct(mrb, value_context, &http_parser_context_type, context);
  if (!context) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
  }

  mrb_get_args(mrb, "|&o", &b, &arg_data);
  if (mrb_nil_p(arg_data)) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
  }
  context->proc = b;
  context->parser.data = context;
  context->was_header_value = TRUE;
  PARSER_SET(context, "headers", mrb_hash_new(mrb));

  http_parser_init(&context->parser, HTTP_REQUEST);

  context->settings.on_url = parser_settings_on_url;
  context->settings.on_header_field = parser_settings_on_header_field;
  context->settings.on_header_value = parser_settings_on_header_value;
  context->settings.on_headers_complete = parser_settings_on_headers_complete;
  if (!mrb_nil_p(b)) {
    context->settings.on_message_complete = parser_settings_on_message_complete;
  }

  if (RSTRING_LEN(arg_data) > 0) {
    char* data = RSTRING_PTR(arg_data);
    size_t len = RSTRING_LEN(arg_data);
    http_parser_execute(&context->parser, &context->settings, data, len);
  }

  return mrb_nil_value();
}
Beispiel #6
0
static
int parser_parse_request(struct http_server_ctx *ctx, struct net_buf *rx)
{
	int rc;

	ctx->field_values_ctr = 0;
	rc = http_parser_execute(&ctx->parser, &ctx->parser_settings,
				 rx->data, rx->len);
	if (rc < 0) {
		printf("[%s:%d] http_parser_execute: %s\n\t%s\n",
		       __func__, __LINE__,
		       http_errno_name(ctx->parser.http_errno),
		       http_errno_description(ctx->parser.http_errno));

		rc = -EINVAL;
		goto exit_routine;
	}

exit_routine:
	return rc;
}
Beispiel #7
0
/* execute(parser, buffer, offset, length) */
static int lhttp_parser_execute (lua_State *L) {
  http_parser* parser = (http_parser *)luaL_checkudata(L, 1, "lhttp_parser");
  size_t chunk_len;
  const char *chunk;
  size_t offset;
  size_t length;
  size_t nparsed;

  luaL_checktype(L, 2, LUA_TSTRING);
  chunk = lua_tolstring(L, 2, &chunk_len);

  offset = luaL_checkint(L, 3);
  length = luaL_checkint(L, 4);

  luaL_argcheck(L, offset < chunk_len, 3, "Offset is out of bounds");
  luaL_argcheck(L, offset + length <= chunk_len, 4,  "Length extends beyond end of chunk");

  nparsed = http_parser_execute(parser, &lhttp_parser_settings, chunk + offset, length);
  lua_pushnumber(L, nparsed);
  return 1;
}
Beispiel #8
0
void
on_head_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t *buf)
{
	ssize_t nparse;
	struct task *task = (struct task*)stream->data;
	http_request *req = task->head_request;
	if (nread > 0) {
		nparse = http_parser_execute(req->http_parser, req->http_parser_setting, buf->base, nread);
		if (nparse < nread) {
			printf("parse incomplete: %ld/%ld parsed\n", nparse, nread);
		}
	} else if (nread < 0) {
		uv_read_stop(stream);
		uv_close((uv_handle_t*)stream, NULL);
		printf("nread < 0\n");
		system("pause");
		exit(-1);
	}

	free(buf->base);
}
Beispiel #9
0
static mrb_value
mrb_http_parser_parse(mrb_state *mrb, mrb_value self)
{
    mrb_value arg_data;
    mrb_value value_context;
    mrb_http_parser_context* context;
    struct RProc *b = NULL;

    value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "parser_context"));
    Data_Get_Struct(mrb, value_context, &http_parser_context_type, context);
    if (!context) {
        mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
    }

    mrb_get_args(mrb, "bo", &b, &arg_data);
    if (mrb_nil_p(arg_data)) {
        mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
    }
    mrb_iv_set(mrb, self, mrb_intern(mrb, "complete_cb"), b ? mrb_obj_value(b) : mrb_nil_value());

    context->parser.data = context;
    context->was_header_value = TRUE;
    CTXV_SET(context, "headers", mrb_hash_new(mrb, 32));

    http_parser_init(&context->parser, HTTP_REQUEST);

    context->settings.on_url = parser_settings_on_url;
    context->settings.on_header_field = parser_settings_on_header_field;
    context->settings.on_header_value = parser_settings_on_header_value;
    context->settings.on_headers_complete = parser_settings_on_headers_complete;
    if (b) {
        context->settings.on_message_complete = parser_settings_on_message_complete;
    }

    if (RSTRING_LEN(arg_data) > 0) {
        http_parser_execute(&context->parser, &context->settings, (char*) RSTRING_PTR(arg_data), RSTRING_CAPA(arg_data));
    }

    return mrb_nil_value();
}
Beispiel #10
0
int processhttp(char* data, int http_length)
{
	if(!start)
		start = time(NULL);
	printf("t=%d\n",t++);
	_init_c_info();
	http_parser_settings settings;
	size_t nparsed;
	memset(&settings, 0, sizeof(settings));
	settings.on_url = on_url;
	settings.on_header_field = on_header_field;
	settings.on_header_value = on_header_value;
	settings.on_body = on_body;

	http_parser parser;
	http_parser_init(&parser, HTTP_REQUEST);
	nparsed = http_parser_execute(&parser, &settings, data, (size_t)http_length);
	http.method = parser.method;

		end = time(NULL);
		printf("%fms\n", difftime(end, start)/t);

	//test
	_print_c_info();

	if (nparsed != (size_t)http_length) 
	{
	    printf( "Error: %s (%s)\n",
	            http_errno_description(HTTP_PARSER_ERRNO(&parser)),
	            http_errno_name(HTTP_PARSER_ERRNO(&parser)));
	}
	if(content_length !=  con_len && http.method == 3 && http_length < 4096)
	{
		memcpy(http.content, data, http_length);
		return FALSE;
	}

	return TRUE;
}
Beispiel #11
0
static void conn_handler(struct fbr_context *fctx, void *_arg)
{
	int fd = *(int *)_arg;
	time_t now;
	char *ct;
	http_parser_settings settings;
	http_parser parser;
	char buf[BUFSIZ];
	size_t nparsed;
	ssize_t retval;
	struct parser_arg parg;

	memset(&settings, 0x00, sizeof(settings));
	settings.on_headers_complete = on_headers_complete;
	http_parser_init(&parser, HTTP_REQUEST);
	parg.fctx = fctx;
	parg.fd = fd;
	parg.finish = 0;
	parser.data = &parg;

	for (;;) {
		retval = fbr_read(fctx, fd, buf, sizeof(buf));
		if (0 > retval)
			err(EXIT_FAILURE, "fbr_read");
		if (0 == retval)
			break;

		nparsed = http_parser_execute(&parser, &settings, buf, retval);

		if (nparsed != retval)
			errx(EXIT_FAILURE, "error parsing HTTP");

		if (parg.finish)
			break;
	}

	shutdown(fd, SHUT_RDWR);
	close(fd);
}
Beispiel #12
0
static int parse_response(transport_http *t)
{
	int ret = 0;
	http_parser_settings settings;
	char buffer[1024];
	gitno_buffer buf;

	http_parser_init(&t->parser, HTTP_RESPONSE);
	t->parser.data = t;
	t->transfer_finished = 0;
	memset(&settings, 0x0, sizeof(http_parser_settings));
	settings.on_header_field = on_header_field;
	settings.on_header_value = on_header_value;
	settings.on_headers_complete = on_headers_complete;
	settings.on_body = on_body_parse_response;
	settings.on_message_complete = on_message_complete;

	gitno_buffer_setup((git_transport *)t, &buf, buffer, sizeof(buffer));

	while(1) {
		size_t parsed;

		if ((ret = gitno_recv(&buf)) < 0)
			return -1;

		parsed = http_parser_execute(&t->parser, &settings, buf.data, buf.offset);
		/* Both should happen at the same time */
		if (parsed != buf.offset || t->error < 0)
			return t->error;

		gitno_consume_n(&buf, parsed);

		if (ret == 0 || t->transfer_finished || t->pack_ready) {
			return 0;
		}
	}

	return ret;
}
Beispiel #13
0
static mrb_value
mrb_http_parser_execute(mrb_state *mrb, mrb_value self)
{
  mrb_value arg_data;
  mrb_value value_context;
  mrb_http_parser_context* context;

  value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "context"));
  Data_Get_Struct(mrb, value_context, &http_parser_context_type, context);
  if (!context) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
  }

  mrb_get_args(mrb, "o", &arg_data);
  if (mrb_nil_p(arg_data)) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument");
  }

  http_parser_execute(&context->parser, &context->settings, (char*) RSTRING_PTR(arg_data), RSTRING_CAPA(arg_data));

  return mrb_nil_value();
}
Beispiel #14
0
int bench(int iter_count, int silent) {
    struct http_parser parser;
    int i;
    int err;
    struct timeval start;
    struct timeval end;
    float rps;

    if (!silent) {
        err = gettimeofday(&start, NULL);
        assert(err == 0);
    }

    for (i = 0; i < iter_count; i++) {
        size_t parsed;
        http_parser_init(&parser, HTTP_REQUEST);

        parsed = http_parser_execute(&parser, &settings, data, data_len);
        assert(parsed == data_len);
    }

    if (!silent) {
        err = gettimeofday(&end, NULL);
        assert(err == 0);

        fprintf(stdout, "Benchmark result:\n");

        rps = (float) (end.tv_sec - start.tv_sec) +
              (end.tv_usec - start.tv_usec) * 1e-6f;
        fprintf(stdout, "Took %f seconds to run\n", rps);

        rps = (float) iter_count / rps;
        fprintf(stdout, "%f req/sec\n", rps);
        fflush(stdout);
    }

    return 0;
}
Beispiel #15
0
int test(const char* req)
{
	int nread = strlen(req);
	http_request_t  request;

	memset(&request, 0 , sizeof(request));
	
	memset(&parser, 0 ,sizeof(parser));
	
	
	
	parser.data = &request ;
	
	int parsed , i ;
	http_parser_init(&parser, HTTP_REQUEST);
	
	for (i = 0 ; i < nread; i++)	
	{
		
		parsed=  http_parser_execute( &parser, &settings, req+i, 1);
		if (parsed < 1) 
		 {
			printf("parser error %d %d", parsed, nread );
		 }
	}	
	
	 
	 
	 printf("request url %s method %s body %s\n", request.url, request.method, request.body );
	 
	
	 for (i=0 ; i < request.header_lines ; i++ )
	 {
		printf("header %s - %s\n", request.header_field[i], request.header_value[i]);
	 }
	 return 0; 
	
}
Beispiel #16
0
struct turbo_parser_wrapper *turbo_parser_wrapper_init(
    const char* data,
    size_t len,
    int32_t type)
{
    struct turbo_parser_wrapper *dest = malloc(
                                            sizeof(struct turbo_parser_wrapper));
    if (!dest)
        return 0;
    dest->parser.data = dest;
    dest->url_str = 0;
    dest->hkv = 0;
    dest->hkv_sz = 0;
    dest->hkv_mem = 0;
    dest->headers_complete = false;
    dest->_state = NOTHING;
    if (type == 0)
        http_parser_init(&dest->parser, HTTP_REQUEST);
    else
        http_parser_init(&dest->parser, HTTP_RESPONSE);
    dest->parsed_sz = http_parser_execute(&dest->parser, &settings, data, len);
    return dest;
}
Beispiel #17
0
/* execute(parser, buffer, offset, length) */
static int lhttp_parser_execute (lua_State *L) {
  http_parser* parser = (http_parser *)luaL_checkudata(L, 1, "lhttp_parser");
  size_t chunk_len;
  const char *chunk;
  size_t offset;
  size_t length;
  size_t nparsed;

  MemSlice *ms = luaL_checkudata(L, 2, "lev.buffer");
  chunk = (const char *)ms->slice;
  chunk_len = ms->until;

  offset = luaL_checkint(L, 3);
  length = luaL_checkint(L, 4);

  luaL_argcheck(L, offset < chunk_len, 3, "Offset is out of bounds");
  luaL_argcheck(L, offset + length <= chunk_len, 4,  "Length extends beyond end of chunk");

  nparsed = http_parser_execute(parser, &lhttp_parser_settings, chunk + offset, length);

  lua_pushnumber(L, nparsed);
  return 1;
}
Beispiel #18
0
static void read_callback(struct ev_loop *loop, struct ev_io *w, int revents) {

	char buf[8192];
	ssize_t len;
	struct bb_reader *bbr = (struct bb_reader *) w;
	struct bb_session *bbs = bbr->session ;
	len = bbs->acceptor->read(bbs, buf, 8192);
	if (len > 0) {
		// if no request is initialized, allocate it
		if (bbs->new_request) {
			//printf("allocating a new request\n");
			if (!bb_new_request(bbs)) goto clear;
		}
		if (bbs->requests_tail->type == 0) {
			int res = http_parser_execute(&bbs->requests_tail->parser, &bb_http_parser_settings, buf, len);
			if (res != len) goto clear;
		}
		else if (bbs->requests_tail->type == BLASTBEAT_TYPE_WEBSOCKET) {
			if (bb_manage_websocket(bbs->requests_tail, buf, len)) {
				goto clear;
			}
		}
		//printf("res = %d\n", res);	
		return;
	}
	
	if (len == 0) {
		goto clear;
	}
	if (errno == EINPROGRESS || errno == EAGAIN || errno == EWOULDBLOCK)
		return;
	perror("read_callback error");
	
clear:
	//printf("done\n");
	bb_session_close(bbs);
}
Beispiel #19
0
/* _http_conn_read_cb(): server read callback.
*/
static void
_http_conn_read_cb(uv_stream_t* tcp_u,
                   ssize_t      siz_i,
                   uv_buf_t     buf_u)
{
  u2_hcon* hon_u = (u2_hcon*)(void*) tcp_u;

  u2_lo_open();
  {
    if ( siz_i < 0 ) {
      uv_err_t las_u = uv_last_error(u2L);

      if ( UV_EOF != las_u.code ) {
        uL(fprintf(uH, "http: read: %s\n", uv_strerror(las_u)));
      }
      _http_conn_dead(hon_u);
    }
    else {
      if ( !hon_u->ruc_u ) {
        hon_u->ruc_u = _http_req_new(hon_u);
      }

      if ( siz_i != http_parser_execute(hon_u->ruc_u->par_u,
                                        &_http_settings,
                                        (c3_c*)buf_u.base,
                                        siz_i) )
      {
        uL(fprintf(uH, "http: parse error\n"));
        _http_conn_dead(hon_u);
      }
    }
    if ( buf_u.base ) {
      free(buf_u.base);
    }
  }
  u2_lo_shut(u2_yes);
}
Beispiel #20
0
HTTPScode
https_recv(struct https_request *req, int *code, const char **body, int *len, int msecs_timeout)
{
        BUF_MEM *bm;
        int n, err;

        if (BIO_reset(req->body) != 1) {
                ctx->errstr = _SSL_strerror();
                return (HTTPS_ERR_LIB);
        }
        /* Read loop sentinel set by parser in __on_message_done() */
        while (!req->done) {
                while ((n = BIO_read(req->cbio, ctx->parse_buf,
                            sizeof(ctx->parse_buf))) <= 0) {
                        if ((n = _BIO_wait(req->cbio, msecs_timeout)) != 1) {
                                ctx->errstr = n ? _SSL_strerror() :
                                    "Connection closed";
                                return (HTTPS_ERR_SERVER);
                        }
                }
                if ((err = http_parser_execute(req->parser,
                            &ctx->parse_settings, ctx->parse_buf, n)) != n) {
                        ctx->errstr = http_errno_description(err);
                        return (HTTPS_ERR_SERVER);
                }
        }
        /* XXX - NUL-terminate body for string parsing */
        BIO_write(req->body, "\0", 1);
        BIO_get_mem_ptr(req->body, &bm);
        
        *code = req->parser->status_code;
        *body = bm->data;
        *len = bm->length - 1;
        
        return (HTTPS_OK);
}
Beispiel #21
0
    std::deque<http::Response*> decode(const char* data, size_t length)
    {
        size_t parsed = http_parser_execute(&parser, &settings, data, length);

        if (parsed != length) {
            // TODO(bmahler): joyent/http-parser exposes error reasons.
            failure = true;

            // If we're still writing the body, fail the writer!
            if (writer.isSome()) {
                http::Pipe::Writer writer_ = writer.get(); // Remove const.
                writer_.fail("failed to decode body");
                writer = None();
            }
        }

        if (!responses.empty()) {
            std::deque<http::Response*> result = responses;
            responses.clear();
            return result;
        }

        return std::deque<http::Response*>();
    }
Beispiel #22
0
static void parse_header(int fd, struct http_data *data)
{
    struct http_callbacks callbacks = {
        .data = data,

        .request_method = http_request_method,
        .request_uri    = http_request_uri,
        .http_version   = http_request_version,

        .http_field     = http_field,
        .header_done    = http_request_done
    };

    struct sock sock = { .fd = fd };
    http_parser_init(&parser, &sock);

    do {
        refill_buffer(&sock);

        /* TODO: parser and sock object should be rolled together */
        ssize_t nbytes_p = http_parser_execute(&parser, &sock, &callbacks);
        sock.pos += nbytes_p;
    } while (!http_parser_is_finished(&sock));
}
Beispiel #23
0
int test_http_parser() {
    http_parser_settings settings;
    settings.on_message_begin = NULL;
    settings.on_url = request_url_cb;
    settings.on_status = on_status;
    settings.on_header_field = header_field_cb;
    settings.on_header_value = header_value_cb;
    settings.on_headers_complete = on_headers_complete;
    settings.on_body = on_body;
    settings.on_message_complete = on_message_complete;
    settings.on_chunk_header = NULL;
    settings.on_chunk_complete = NULL;

    http_parser parser;
    http_parser_init(&parser, HTTP_REQUEST);
    Request req;
    parser.data = &req;
    int nparsed = http_parser_execute(&parser, &settings, TEST_POST_REQ.c_str(), TEST_POST_REQ.size());
    LOG_INFO("parsed size:%d, parser->upgrade:%d,total_size:%u", nparsed, parser.upgrade, TEST_POST_REQ.size());
    if (parser.http_errno) {
        LOG_INFO("ERROR:%s", http_errno_description(HTTP_PARSER_ERRNO(&parser)));
    }
    return 0;
}
Beispiel #24
0
size_t response_parser::parse(const char *data, size_t len)
{
    return http_parser_execute(&_parser, &_settings, data, len);
}
// Эта штука срабатывает, когда кто-то нам пишет
void connection::buff_on_read(struct bufferevent *bev, void *ctx) {
    connection* _this = static_cast<connection*>(ctx);

    log << "Sth read\n";

    // буфер с нашими данными
    evbuffer* input = bev->input;

    // копируем всё это дело в строку
    size_t len = evbuffer_get_length(bev->input);
    char* data = new char[len];
    if ((evbuffer_copyout(input, data, len)) < 0) {
        event_base_loopbreak(_this->evbase);
    } else {
        log << "Parsing...\n";
        // ПАРСИМ (TODO: здесь в оригинале должно быть всё красиво. Нужно смотреть тип запроса, обрабатывать все заголовки, вешать нормальные колбеки и много всего.), но сейчас нам важно поолучить только URL

        _this->parser.data = _this; // устанавливаем для парсера связь с внешним миром

        http_parser_settings settings;
        memset(&settings, 0, sizeof(settings));

        // устанавливаем обработчики
        settings.on_url = [](http_parser* p, const char* at, size_t len) -> int {
            // копируем URL
           // printf("Url: %.*s\n", (int)len, at);
            char* t = new char[len-1];
            memset(t, '\0', len*sizeof(char));
            strncpy(t, at+1, len-1); // len-1 т.к. там пробел
            // избавляемся от параметров
            for (char* i = t; *i; ++i) {
                if (*i == '?') { *i = '\0'; break; }
            }
            static_cast<connection*>(p->data)->client_request.uri = t;
            delete t;
            return 0;
        };

        settings.on_header_field = [](http_parser* p, const char* at, size_t len) -> int {return 0;};
        settings.on_header_value = [](http_parser* p, const char* at, size_t len) -> int {return 0;};
        settings.on_headers_complete = [](http_parser*) -> int {return 0;};

        size_t nparsed = http_parser_execute(&_this->parser, &settings, data, len);
        if (nparsed != len) {
            log << "Can't parse\n";
            event_base_loopbreak(_this->evbase);
        }

        // НА ЭТОМ ЭТАПЕ МЫ ВСЁ РАСПАРСИЛИ И ИМЕЕМ ЗАПОЛНЕННЫЙ РЕКВЕСТ (client_request)
//        _this->client_request.method = http_method_str(_this->parser.method);
        log << "URI=" << _this->client_request.uri << std::endl;

        // Пытаемся открыть требуемый файл и скрамливаем его клиенту

        int fd = open(_this->client_request.uri.c_str(), O_RDONLY);
        //вывод имени файла по байтам
//        for (auto& i: _this->client_request.uri) {
//            printf("%d ", i);
//        }
//        puts("");

        // Если не получилось - шлём ошибку
        if (fd < 0) {
            log << "No such file or directory\n";//perror("KEK");
            if ((send(_this->client_sock, response::not_found.c_str(), response::not_found.length(), MSG_NOSIGNAL)) < 0) {
                log << "cant't send!!!\n";
            }
        } else {
            // если всё окей
            if ((send(_this->client_sock, response::ok.c_str(), response::ok.length(), MSG_NOSIGNAL | MSG_MORE)) < 0) {
                log << "can't send\n";
            } else {
                struct stat stat_buf;
                fstat(fd, &stat_buf);

                // Посылаем файл
                ssize_t recv = sendfile( _this->client_sock, fd, nullptr, stat_buf.st_size);
                if (recv != stat_buf.st_size) {
                    log << "file not sent at all\n";
                }
            }

        }

        event_base_loopexit(_this->evbase, nullptr);
    }
}
Beispiel #26
0
void *hpcd_server_handle_connection ( void *arg )
{
    char buffer[80 * 1024];
    int n,
        newsockfd = * ( ( int * ) arg );
    free ( arg );


    /** Set time limit on execution of thread **/

    clock_t begin, end;
    double time_spent = 0;

    begin = clock();


    http_parser_settings settings;
    hpcd_server_http_request *request_container = (hpcd_server_http_request *) malloc ( sizeof ( hpcd_server_http_request ) );
    request_container->complete = 0;


    memset ( &settings, 0, sizeof ( settings ) );
    settings.on_url = hpcd_server_handle_on_url;
    settings.on_message_complete = hpcd_server_handle_on_message_complete;
    settings.on_headers_complete = hpcd_server_handle_on_headers_complete;
    settings.on_header_field = hpcd_server_handle_on_header_field;
    settings.on_header_value = hpcd_server_handle_on_header_value;

    /* Clear the buffer */
    bzero ( buffer, 80 * 1024 );

    http_parser *parser = malloc ( sizeof ( http_parser ) );
    http_parser_init ( parser, HTTP_REQUEST );
    request_container->sock_fd = &newsockfd;
    parser->data = request_container;

    while(!request_container->complete) {

        /* Reading from buffer */
        //printf ( "Reading from buffer: %d\n ", request_container->complete );
        n = recv ( newsockfd, buffer, 80 * 1024, 0 );

        if ( n < 0 )
        {
            printf ( "ERROR reading from socket %d", n );
            exit ( 1 );
        }

        //printf("captured n %d\n", n);

        size_t nparsed = http_parser_execute ( parser, &settings, buffer, n );

        if ( nparsed != ( size_t ) n )
        {
            fprintf ( stderr,
                      "Error: %s (%s)\n",
                      http_errno_description ( HTTP_PARSER_ERRNO ( parser ) ),
                      http_errno_name ( HTTP_PARSER_ERRNO ( parser ) ) );
        }

        bzero ( buffer, n );


        /** Thread execution time **/

        end = clock();
        if (((double)(end - begin) / CLOCKS_PER_SEC) > 60) {
            printf("Request timed out\n");
            close(*request_container->sock_fd);
            break;
        }
    }

    printf("Loop Closed\n");

    return NULL;
}
Beispiel #27
0
int main(int argc, char* argv[]) {
  enum http_parser_type file_type;

  if (argc != 3) {
    usage(argv[0]);
  }

  char* type = argv[1];
  if (type[0] != '-') {
    usage(argv[0]);
  }

  switch (type[1]) {
    /* in the case of "-", type[1] will be NUL */
    case 'r':
      file_type = HTTP_RESPONSE;
      break;
    case 'q':
      file_type = HTTP_REQUEST;
      break;
    case 'b':
      file_type = HTTP_BOTH;
      break;
    default:
      usage(argv[0]);
  }

  char* filename = argv[2];
  FILE* file = fopen(filename, "r");
  if (file == NULL) {
    perror("fopen");
    goto fail;
  }

  fseek(file, 0, SEEK_END);
  long file_length = ftell(file);
  if (file_length == -1) {
    perror("ftell");
    goto fail;
  }
  fseek(file, 0, SEEK_SET);

  char* data = malloc(file_length);
  if (fread(data, 1, file_length, file) != (size_t)file_length) {
    fprintf(stderr, "couldn't read entire file\n");
    free(data);
    goto fail;
  }

  http_parser_settings settings;
  memset(&settings, 0, sizeof(settings));
  settings.on_message_begin = on_message_begin;
  settings.on_url = on_url;
  settings.on_header_field = on_header_field;
  settings.on_header_value = on_header_value;
  settings.on_headers_complete = on_headers_complete;
  settings.on_body = on_body;
  settings.on_message_complete = on_message_complete;

  http_parser parser;
  http_parser_init(&parser, file_type);
  size_t nparsed = http_parser_execute(&parser, &settings, data, file_length);
  free(data);

  if (nparsed != (size_t)file_length) {
    fprintf(stderr,
            "Error: %s (%s)\n",
            http_errno_description(HTTP_PARSER_ERRNO(&parser)),
            http_errno_name(HTTP_PARSER_ERRNO(&parser)));
    goto fail;
  }

  return EXIT_SUCCESS;

fail:
  fclose(file);
  return EXIT_FAILURE;
}
Beispiel #28
0
size_t mweb_http_request_parser(mweb_http_request_t* request, const char* base, size_t len){
    return http_parser_execute(&request->parser, &simple_settings, base, len);
}
Beispiel #29
0
size_t
execute_parse(client_t *cli, const char *data, size_t len)
{
  return http_parser_execute(cli->http, &settings, data, len);
}
Beispiel #30
0
    return 0;
}

size_t script_verify_request(lua_State *L) {
    http_parser_settings settings = {
        .on_message_complete = verify_request
    };
    http_parser parser;
    char *request = NULL;
    size_t len, count = 0;

    script_request(L, &request, &len);
    http_parser_init(&parser, HTTP_REQUEST);
    parser.data = &count;

    size_t parsed = http_parser_execute(&parser, &settings, request, len);

    if (parsed != len || count == 0) {
        enum http_errno err = HTTP_PARSER_ERRNO(&parser);
        const char *desc = http_errno_description(err);
        const char *msg = err != HPE_OK ? desc : "incomplete request";
        int line = 1, column = 1;

        for (char *c = request; c < request + parsed; c++) {
            column++;
            if (*c == '\n') {
                column = 1;
                line++;
            }
        }