On Sun, Oct 09, 2016 at 01:51:36PM -0400, Littlefield, Tyler wrote: > All, > I sent this a while ago. I'm currently working on a passthrough proxy
Hi, Can you post here a link (for "a while ago" thing)? > for a larger project. I've pasted the code here, but for whatever reason > when I connect my data does not get sent through to the other side. I > have debugged it to know that: > 1) the requests are parsed correctly. > 2) The connection is made. > 3) The data is moved from one buffer to the next at the end of OnRead. > Does anyone have any thoughts? I'm struggling to figure out why the data > wouldn't be sent. Any tips would be greatly appreciated. I've dropped > the relevant code here. You can take a look at [1] for example. [1]: https://github.com/libevent/libevent/blob/b9c5077e99b8be6ec1fab2fb8177439ef9cb76e1/sample/le-proxy.c#L51 > struct State > { > bufferevent* origenation; > bufferevent* connection; > Listener* listener; > RequestState state; > }; > > void Listener::Listen(event_base* base) > { > _base = base; I guess this is global. > _listener = evconnlistener_new_bind(base, AcceptConnectionCallback, > (void*)this, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (struct > sockaddr *)&_addr, sizeof(_addr)); > if (!_listener) > { > int err = EVUTIL_SOCKET_ERROR(); > throw std::runtime_error("Could not create listener, got > error: "+std::string(evutil_socket_error_to_string(err))+"."); > } > > evconnlistener_set_error_cb(_listener, AcceptErrorCallback); So somewhere you called event_base_dispatch() > } > > void Listener::OnRead(bufferevent *bufferevt, State* state) > { > evbuffer *src = nullptr; > evbuffer* dst = nullptr; > size_t len = 0; > > if (state->origenation == bufferevt) > { > src = bufferevent_get_input(bufferevt); > if (state->connection) > dst = bufferevent_get_output(state->connection); > } > else > { > src = bufferevent_get_input(state->connection); > dst = bufferevent_get_output(state->origenation); > } So you have a bidirectional connections, are you sure that this part actually works? > > len = evbuffer_get_length(src); > if (bufferevt == state->origenation) > { > if (state->state == RequestState::Half) > { > if (result) > { > std::string response = > "<html>\n<head>\n<title>Error!</title>\n</head>\n<body>\n"; > response += "<h1>An error has > occured.</h1>\n<p>\n"; > response += > std::string(gai_strerror(result)) + "</p>\n</body>\n</html>\n"; > dst = bufferevent_get_output(bufferevt); > evbuffer_copyout(dst, > (void*)response.c_str(), response.length()); Does this works? > evbuffer_drain(src, len); > return; > } > > > state->connection = bufferevent_socket_new(_base, > -1, BEV_OPT_CLOSE_ON_FREE); Please send code without wrapping, and use attachments for this. > result = > bufferevent_socket_connect(state->connection, servinfo->ai_addr, > servinfo->ai_addrlen); You can just use buffervent_socket_connect_hostname() instead of doing this manually. > dst = bufferevent_get_output(state->connection); So what you have now is just a socket that doesn't meant to be connected, since it is NONBLOCK you can take a look at [2] to see how you can handle it, and of course it will not work for you, until you will connect to it. [2]: https://github.com/libevent/libevent/blob/b9c5077e99b8be6ec1fab2fb8177439ef9cb76e1/http.c#L1553 > bufferevent_setcb(state->connection, ReadCallback, > NULL, EventCallback, (void*)state); > bufferevent_enable(state->connection, EV_READ|EV_WRITE); > } > } > > evbuffer_add_buffer(dst, src); > } And it will be far more better if you will provide working 50L sample. Azat *********************************************************************** To unsubscribe, send an e-mail to [email protected] with unsubscribe libevent-users in the body.
