PUBLIC int httpConnect(HttpConn *conn, cchar *method, cchar *uri, struct MprSsl *ssl) { assert(conn); assert(method && *method); assert(uri && *uri); if (httpServerConn(conn)) { httpError(conn, HTTP_CODE_BAD_GATEWAY, "Cannot call connect in a server"); return MPR_ERR_BAD_STATE; } if (conn->tx == 0 || conn->state != HTTP_STATE_BEGIN) { /* WARNING: this will erase headers */ httpPrepClientConn(conn, 0); } assert(conn->state == HTTP_STATE_BEGIN); conn->tx->parsedUri = httpCreateUri(uri, HTTP_COMPLETE_URI_PATH); if (openConnection(conn, ssl) == 0) { return MPR_ERR_CANT_OPEN; } conn->authRequested = 0; conn->tx->method = supper(method); conn->startMark = mprGetHiResTicks(); /* The receive pipeline is created when parsing the response in parseIncoming() */ httpCreateTxPipeline(conn, conn->http->clientRoute); httpSetState(conn, HTTP_STATE_CONNECTED); setDefaultHeaders(conn); return 0; }
PUBLIC int httpConnect(HttpStream *stream, cchar *method, cchar *url, MprSsl *ssl) { HttpNet *net; HttpTx *tx; HttpUri *uri; cchar *ip, *protocol; int port; assert(stream); assert(method && *method); assert(url && *url); net = stream->net; if (httpServerStream(stream)) { mprLog("client error", 0, "Cannot call httpConnect() in a server"); return MPR_ERR_BAD_STATE; } if (net->protocol <= 0) { mprLog("client error", 0, "HTTP protocol to use has not been defined"); return MPR_ERR_BAD_STATE; } if (stream->tx == 0 || stream->state != HTTP_STATE_BEGIN) { httpResetClientStream(stream, 0); } tx = stream->tx; tx->method = supper(method); stream->authRequested = 0; stream->startMark = mprGetHiResTicks(); if ((uri = tx->parsedUri = httpCreateUri(url, HTTP_COMPLETE_URI_PATH)) == 0) { return MPR_ERR_BAD_ARGS; } ssl = uri->secure ? (ssl ? ssl : mprCreateSsl(0)) : 0; httpGetUriAddress(uri, &ip, &port); if (net->sock) { if (net->error) { mprCloseSocket(net->sock, 0); net->sock = 0; } else if (canUse(net, stream, uri, ssl, ip, port)) { httpLog(net->trace, "client.connection.reuse", "context", "reuse:%d", stream->keepAliveCount); } else { if (net->protocol >= 2) { if (mprGetListLength(net->streams) > 1) { httpError(stream, HTTP_CODE_COMMS_ERROR, "Cannot use network for %s due to other existing requests", ip); return MPR_ERR_CANT_FIND; } } else { mprCloseSocket(net->sock, 0); net->sock = 0; } } } if (!net->sock) { if (httpConnectNet(net, ip, port, ssl) < 0) { return MPR_ERR_CANT_CONNECT; } stream->net = net; stream->sock = net->sock; stream->ip = net->ip; stream->port = net->port; stream->keepAliveCount = (net->protocol >= 2) ? 0 : stream->limits->keepAliveMax; #if ME_HTTP_WEB_SOCKETS if (net->protocol == 1 && uri->webSockets && httpUpgradeWebSocket(stream) < 0) { stream->errorMsg = net->errorMsg = net->sock->errorMsg; return 0; } #endif } httpCreatePipeline(stream); setDefaultHeaders(stream); httpSetState(stream, HTTP_STATE_CONNECTED); protocol = net->protocol < 2 ? "HTTP/1.1" : "HTTP/2"; httpLog(net->trace, "client.request", "request", "method='%s', url='%s', protocol='%s'", tx->method, url, protocol); return 0; }