static void proxy_close(liVRequest *vr, liPlugin *p) { proxy_connection *pcon = (proxy_connection*) g_ptr_array_index(vr->plugin_ctx, p->id); g_ptr_array_index(vr->plugin_ctx, p->id) = NULL; if (pcon) { if (vr->out->limit) vr->out->limit->io_watcher = NULL; proxy_connection_free(pcon); } }
static void connection_poll( ProxyConnection* root, ProxySelect* sel ) { DataStatus ret = DATA_NEED_MORE; Connection* conn = (Connection*)root; int fd = root->socket; if (!proxy_select_poll(sel, fd)) return; switch (conn->state) { case STATE_CONNECTING: PROXY_LOG("%s: connected to http proxy, sending header", root->name); conn->state = STATE_SEND_HEADER; break; case STATE_SEND_HEADER: ret = proxy_connection_send(root, fd); if (ret == DATA_COMPLETED) { conn->state = STATE_RECEIVE_ANSWER_LINE1; PROXY_LOG("%s: header sent, receiving first answer line", root->name); } break; case STATE_RECEIVE_ANSWER_LINE1: case STATE_RECEIVE_ANSWER_LINE2: ret = proxy_connection_receive_line(root, root->socket); if (ret == DATA_COMPLETED) { if (conn->state == STATE_RECEIVE_ANSWER_LINE1) { int http1, http2, codenum; const char* line = root->str->s; if ( sscanf(line, "HTTP/%d.%d %d", &http1, &http2, &codenum) != 3 ) { PROXY_LOG( "%s: invalid answer from proxy: '%s'", root->name, line ); ret = DATA_ERROR; break; } /* success is 2xx */ if (codenum/2 != 100) { PROXY_LOG( "%s: connection refused, error=%d", root->name, codenum ); proxy_connection_free( root, 0, PROXY_EVENT_CONNECTION_REFUSED ); return; } PROXY_LOG("%s: receiving second answer line", root->name); conn->state = STATE_RECEIVE_ANSWER_LINE2; proxy_connection_rewind(root); } else { /* ok, we're connected */ PROXY_LOG("%s: connection succeeded", root->name); proxy_connection_free( root, 1, PROXY_EVENT_CONNECTED ); } } break; default: PROXY_LOG("%s: invalid state for read event: %d", root->name, conn->state); } if (ret == DATA_ERROR) { proxy_connection_free( root, 0, PROXY_EVENT_SERVER_ERROR ); } }