{"action":"created","issue":{"url":"https://api.github.com/repos/criticalstack/libevhtp/issues/110","repository_url":"https://api.github.com/repos/criticalstack/libevhtp","labels_url":"https://api.github.com/repos/criticalstack/libevhtp/issues/110/labels{/name}","comments_url":"https://api.github.com/repos/criticalstack/libevhtp/issues/110/comments","events_url":"https://api.github.com/repos/criticalstack/libevhtp/issues/110/events","html_url":"https://github.com/criticalstack/libevhtp/issues/110","id":361611857,"node_id":"MDU6SXNzdWUzNjE2MTE4NTc=","number":110,"title":"How to stream request body data","user":{"login":"patrickjane","id":1404715,"node_id":"MDQ6VXNlcjE0MDQ3MTU=","avatar_url":"https://avatars0.githubusercontent.com/u/1404715?v=4","gravatar_id":"","url":"https://api.github.com/users/patrickjane","html_url":"https://github.com/patrickjane","followers_url":"https://api.github.com/users/patrickjane/followers","following_url":"https://api.github.com/users/patrickjane/following{/other_user}","gists_url":"https://api.github.com/users/patrickjane/gists{/gist_id}","starred_url":"https://api.github.com/users/patrickjane/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/patrickjane/subscriptions","organizations_url":"https://api.github.com/users/patrickjane/orgs","repos_url":"https://api.github.com/users/patrickjane/repos","events_url":"https://api.github.com/users/patrickjane/events{/privacy}","received_events_url":"https://api.github.com/users/patrickjane/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-09-19T07:20:38Z","updated_at":"2018-09-19T11:42:09Z","closed_at":null,"author_association":"NONE","body":"I am working on a middleware-based implementation (similar to Node.JS' express) that uses `libevhtp` underneath the hood and is written in C++.\r\n\r\nBasically, I am using a single callback hook (using `evhtp_set_gencb`), which then creates the necessary C++ objects and injects the request into my framework.  \r\nWith this approach, I am bound to use whatever resources are provided by `libevhtp` at the time the callback is called. This means, the whole body will be read already, and reside in `req->buffer_in`. While this may work for smaller requests, it is clearly suboptimal for larger requests or file uploads.\r\n\r\nNow I stumbled upon https://gist.github.com/errzey/4040484, which gives sample code for streaming data (to e.g. the filesystem) using the `evhtp_hook_on_read` hook. This looks good at first sight, however I am curious what the order of callbacks will be? The sample code instantly returns `EVHTP_RES_OK` in `stuff_callback`, so I suppose this happens *after* all data was read and provided by the `stuff_onread_callback`? If so, this might not work out for my case, since my framework is only triggered from within the request callback (`stuff_callback` in that example), so I would end up in the same situation, that the payload is fully transferred at the point my code is reached.\r\n\r\nSo I am not quite sure how I could hook this kind of functionality correctly into my implementation. Basically I would need something like:\r\n\r\n1) Request callback from `evhtp_set_gencb` is called - body is *not yet read*\r\n2) My stuff is triggered, C++ objects are created, etc.\r\n3) Decide to a) fully load body contents or b) provide some kind of streaming API (e.g. decide by content-length)\r\n4) Send the request down my C++ pipeline for the enduser of my framework\r\n\r\nHope this was understandable. Do you guys have any hint for a viable approach in my situation?"},"comment":{"url":"https://api.github.com/repos/criticalstack/libevhtp/issues/comments/422769199","html_url":"https://github.com/criticalstack/libevhtp/issues/110#issuecomment-422769199","issue_url":"https://api.github.com/repos/criticalstack/libevhtp/issues/110","id":422769199,"node_id":"MDEyOklzc3VlQ29tbWVudDQyMjc2OTE5OQ==","user":{"login":"NathanFrench","id":28454863,"node_id":"MDQ6VXNlcjI4NDU0ODYz","avatar_url":"https://avatars3.githubusercontent.com/u/28454863?v=4","gravatar_id":"","url":"https://api.github.com/users/NathanFrench","html_url":"https://github.com/NathanFrench","followers_url":"https://api.github.com/users/NathanFrench/followers","following_url":"https://api.github.com/users/NathanFrench/following{/other_user}","gists_url":"https://api.github.com/users/NathanFrench/gists{/gist_id}","starred_url":"https://api.github.com/users/NathanFrench/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NathanFrench/subscriptions","organizations_url":"https://api.github.com/users/NathanFrench/orgs","repos_url":"https://api.github.com/users/NathanFrench/repos","events_url":"https://api.github.com/users/NathanFrench/events{/privacy}","received_events_url":"https://api.github.com/users/NathanFrench/received_events","type":"User","site_admin":false},"created_at":"2018-09-19T11:42:09Z","updated_at":"2018-09-19T11:42:09Z","author_association":"MEMBER","body":"Have you looked at https://github.com/criticalstack/libevhtp/blob/develop/examples/example_chunked.c\r\n?\r\n"}}
{"actor":{"display_login":"NathanFrench"}}