Esempio n. 1
0
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 );
    }
}