示例#1
0
void SNetStorageObjectRPC::Close()
{
    if (m_State == eReady)
        return;

    CNetServerConnection conn_copy(m_Connection);
    m_Connection = NULL;

    if (m_State == eReading) {
        m_State = eReady;

        if (!m_EOF) {
            m_UTTPReader.Reset();
            conn_copy->Close();
        }
    } else { /* m_State == eWriting */
        m_State = eReady;

        CSocket& sock = conn_copy->m_Socket;

        s_SendEndOfData(sock);

        CReadJsonFromSocket message_reader;

        s_TrapErrors(m_OriginalRequest,
                message_reader.ReadMessage(sock), sock,
                m_NetStorageRPC->m_Config.err_mode);
    }
}
示例#2
0
static int net_connect_req_handler(struct net_handle_cxt* cxt,
                                   struct net_req* req) {
    PLOGD("Entering CONNECT handler!");
    struct strbuf* buf = &req->data->buf;
    PLOGD("HTTP/%d.%d", req->ver_major, req->ver_minor);
    req->host = req->path;
    PLOGD("Host: %s", buf->p + req->host);
    PLOGD("Port: %d", req->port);

    struct conn* client = cxt->client;
    PLOGD("From client: %s", ep_tostring(&client->ep));
    
    struct conn* server = net_connect_to_server(cxt, buf->p + req->host, 
                                                htons(req->port));
    
    if (server == NULL) {
        // No server available
        net_bad_gateway(client);
        return -1;
    }
    
    struct net_handle_list* p = mem_alloc(sizeof(struct net_handle_list));
    p->server = server;
    mem_incref(server);
    p->next = NULL;
    p->req = req;
    mem_incref(req);
    
    if (cxt->head == NULL)
        cxt->head = cxt->tail = p;
    else {
        cxt->tail->next = p;
        cxt->tail = p;
    }
    
    event_post(cxt->ev_notice_rsp, (void*)1);
    
    static char msg[] = "HTTP/1.1 200 OK\r\n\r\n";
    int ret = conn_write(client, msg, strlen(msg));
    
    if (ret) {
        net_bad_gateway(client);
        mem_decref(server, conn_done);
        return -1;
    }
    
    while (1) {
        ret = conn_copy(server, client, 64*1024);
        if (ret)
            break;
    }
    
    PLOGI("%s CONNECT %s %d", ep_tostring(client), 
                              buf->p + req->host,
                              client->tx);
    mem_decref(server, conn_done);
    return ret;
}
示例#3
0
static int net_connect_rsp_handler(struct net_handle_cxt* cxt,
                          struct conn* server) {
    struct conn* client = cxt->client;
    int ret;
    while (1) {
        ret = conn_copy(client, server, 64*1024);
        if (ret)
            break;
    }
    return ret;
}
示例#4
0
static int net_transfer_body_HTTP_1_1(struct conn* dst,
                             struct conn* src,
                             struct net_data* data) {
    if (strcmp(data->buf.p, "HEAD") == 0)
        return 0;
    
    int ret = 0;
    char* keyval = net_data_get_ent(data, "Transfer-Encoding");
    if (keyval == NULL || strcmp(keyval, "chunked")) {
        // Not chunked encoding
        keyval = net_data_get_ent(data, "Content-Length");
        int len = 0;
        if (keyval)
            len += atoi(keyval);
        if (len > 0) {
            ret = conn_copy(dst, src, len);
            if (ret)
                return ret;
        }
        return 0;
    }
    
    // Transfer-Encoding: chunked
    // FIXME HTTP rfc tells that proxy should forward decoded body
    struct strbuf buf;
    strbuf_init(&buf);
    while (1) {
        strbuf_reset(&buf);
        ret = conn_gets(src, HTTP_CHUNK_HEADER_MAXLEN, &buf);
        if (ret <= 0) {
            ret = -1;
            break;
        }
        
        strbuf_cat(&buf, "\r\n");
        ret = conn_write(dst, buf.p, buf.len);
        if (ret) {
            break;
        }
        
        int len = -1;
        sscanf(buf.p, "%x", &len);
        if (len == 0) {
            // Last chunck
            ret = 0;
            break;
        }
        
        // Also copy the \r\n
        ret = conn_copy(dst, src, len+2);
        if (ret)
            break;
    }
    if (ret == 0) {
        // Chunked trailer part
        while (1) {
            strbuf_reset(&buf);
            ret = conn_gets(src, HTTP_HEADER_MAXLEN, &buf);
            if (ret < 0)
                return ret;
            strbuf_cat(&buf, "\r\n");
            if (conn_write(dst, buf.p, buf.len)) {
                ret = -1;
                break;
            }
            if (ret == 0)
                break;
        }
    }
    strbuf_done(&buf);
    return ret;
}
示例#5
0
static int net_http_rsp_handler(struct net_handle_cxt* cxt,
                                struct conn* server) {
    struct conn* client = cxt->client;
    
    client->tx = 0;
    
    struct net_data* data = mem_alloc(sizeof(struct net_data));
    net_data_init(data);
    int ret = net_fetch_http(server, data);
    if (ret) {
        // Failed to fetch response from server
        conn_close(server);
        net_bad_gateway(client);
        net_data_done(data);
        mem_free(data);
        return ret;
    }
    
    struct net_rsp rsp;
    memset(&rsp, 0, sizeof(rsp));
    rsp.data = data;
    ret = net_parse_rsp(&rsp);
    if (ret) {
        conn_close(server);
        net_bad_gateway(client);
        net_rsp_done(&rsp);
        return ret;
    }
    
    // TODO check headers and http version
    
    ret = net_forward_rsp_header(&rsp, client);
    if (ret) {
        net_rsp_done(&rsp);
        return ret;
    }
    
    if (rsp.ver_major*100 + rsp.ver_minor > 100) {
        // Higher than http 1.0
        ret = net_transfer_body_HTTP_1_1(client, server, rsp.data);
    } else {
        PLOGD("Forwarding http 1.0 response");
        while (1) {
            ret = conn_copy(client, server, 64*1024);
            if (ret < 0) {
                ret = 0;
                break;
            }
        }
        conn_close(client);
        conn_close(server);
    }
    
    struct net_req* req = cxt->head->req;
    
    if (ret == 0)
        ret = rsp.code;
    
    // WTF... 
    log_http_req(&client->ep, req->data->buf.p + req->host, 
                 req->data->buf.p + req->path, client->tx);

    PLOGI("%s %s %s:%d%s %d", ep_tostring(&client->ep),
                            req->data->buf.p,
                            req->data->buf.p + req->host,
                            req->port,
                            req->data->buf.p + req->path,
                            client->tx);
    net_rsp_done(&rsp);
    return ret;
}