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; }
/* function form(uri: String = null, formData: Object = null): Http Issue a POST method with form data */ static EjsHttp *http_form(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv) { EjsObj *data; if (argc == 2 && !ejsIs(ejs, argv[1], Null)) { /* Prep here to reset the state. The ensures the current headers will be preserved. Users may have called setHeader to define custom headers. Users must call reset if they want to clear prior headers. */ httpPrepClientConn(hp->conn, 1); mprFlushBuf(hp->requestContent); data = argv[1]; if (ejsGetLength(ejs, data) > 0) { prepForm(ejs, hp, NULL, data); } else { mprPutStringToBuf(hp->requestContent, ejsToMulti(ejs, data)); } mprAddNullToBuf(hp->requestContent); httpSetHeader(hp->conn, "Content-Type", "application/x-www-form-urlencoded"); /* Ensure this gets recomputed */ httpRemoveHeader(hp->conn, "Content-Length"); } return startHttpRequest(ejs, hp, "POST", argc, argv); }
static int prepRequest(HttpConn *conn, MprList *files, int retry) { MprKeyValue *header; char *seq; int next; httpPrepClientConn(conn, retry); for (next = 0; (header = mprGetNextItem(app->headers, &next)) != 0; ) { if (scaselessmatch(header->key, "User-Agent")) { httpSetHeader(conn, header->key, header->value); } else { httpAppendHeader(conn, header->key, header->value); } } if (app->text) { httpSetHeader(conn, "Accept", "text/plain"); } if (app->sequence) { static int next = 0; seq = itos(next++); httpSetHeader(conn, "X-Http-Seq", seq); } if (app->ranges) { httpSetHeader(conn, "Range", app->ranges); } if (app->formData) { httpSetHeader(conn, "Content-Type", "application/x-www-form-urlencoded"); } if (setContentLength(conn, files) < 0) { return MPR_ERR_CANT_OPEN; } return 0; }
int httpConnect(HttpConn *conn, cchar *method, cchar *url, struct MprSsl *ssl) { mprAssert(conn); mprAssert(method && *method); mprAssert(url && *url); if (conn->endpoint) { httpError(conn, HTTP_CODE_BAD_GATEWAY, "Can't call connect in a server"); return MPR_ERR_BAD_STATE; } mprLog(4, "Http: client request: %s %s", method, url); if (conn->tx == 0 || conn->state != HTTP_STATE_BEGIN) { /* WARNING: this will erase headers */ httpPrepClientConn(conn, 0); } mprAssert(conn->state == HTTP_STATE_BEGIN); httpSetState(conn, HTTP_STATE_CONNECTED); conn->setCredentials = 0; conn->tx->method = supper(method); #if BIT_DEBUG conn->startTime = conn->http->now; conn->startTicks = mprGetTicks(); #endif if (openConnection(conn, url, ssl) == 0) { return MPR_ERR_CANT_OPEN; } httpCreateTxPipeline(conn, conn->http->clientRoute); if (setClientHeaders(conn) < 0) { return MPR_ERR_CANT_INITIALIZE; } return 0; }
/* function WebSocket(uri: Uri, protocols = null, options) options = { certificate: Path, verify: Boolean, } */ static EjsWebSocket *wsConstructor(Ejs *ejs, EjsWebSocket *ws, int argc, EjsObj **argv) { EjsAny *certificate; bool verify; assert(ejsIsPot(ejs, ws)); ejsLoadHttpService(ejs); ws->ejs = ejs; verify = 0; ws->uri = httpUriToString(((EjsUri*) argv[0])->uri, 0); if (argc >= 2) { if (ejsIs(ejs, argv[1], Array)) { ws->protocols = sclone((ejsToString(ejs, argv[1]))->value); } else if (ejsIs(ejs, argv[1], String)) { ws->protocols = sclone(((EjsString*) argv[1])->value); } else { ws->protocols = sclone("chat"); } } else { ws->protocols = sclone("chat"); } if (*ws->protocols == '\0') { ejsThrowArgError(ejs, "Bad protocol"); return 0; } if (argc >= 3) { ws->frames = ejsGetPropertyByName(ejs, argv[2], EN("frames")) == ESV(true); verify = ejsGetPropertyByName(ejs, argv[2], EN("verify")) == ESV(true); if ((certificate = ejsGetPropertyByName(ejs, argv[2], EN("certificate"))) != 0) { ws->certFile = ejsToMulti(ejs, argv[0]); } } if ((ws->conn = httpCreateConn(MPR->httpService, NULL, ejs->dispatcher)) == 0) { ejsThrowMemoryError(ejs); return 0; } httpSetAsync(ws->conn, 1); httpPrepClientConn(ws->conn, 0); httpSetConnNotifier(ws->conn, webSocketNotify); httpSetWebSocketProtocols(ws->conn, ws->protocols); httpSetConnContext(ws->conn, ws); if (sstarts(ws->uri, "wss")) { ws->ssl = mprCreateSsl(0); mprVerifySslIssuer(ws->ssl, verify); mprVerifySslPeer(ws->ssl, verify); #if FUTURE if (!hp->caFile) { //MOB - Some define for this. hp->caFile = mprJoinPath(mprGetAppDir(), "http-ca.crt"); } mprSetSslCaFile(hp->ssl, hp->caFile); mprSetSslCaFile(hp->ssl, mprJoinPath(mprGetAppDir(), "http-ca.crt")); #endif } startWebSocketRequest(ejs, ws); return ws; }
/* function close(): Void */ static EjsObj *http_close(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv) { if (hp->conn) { httpFinalize(hp->conn); sendHttpCloseEvent(ejs, hp); httpDestroyConn(hp->conn); // TODO OPT - Better to do this on demand. This consumes a conn until GC. hp->conn = httpCreateConn(ejs->http, NULL, ejs->dispatcher); httpPrepClientConn(hp->conn, 0); httpSetConnNotifier(hp->conn, httpEventChange); httpSetConnContext(hp->conn, hp); } return 0; }
/* function Http(uri: Uri = null) */ static EjsHttp *httpConstructor(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv) { ejsLoadHttpService(ejs); hp->ejs = ejs; if ((hp->conn = httpCreateConn(ejs->http, NULL, ejs->dispatcher)) == 0) { ejsThrowMemoryError(ejs); return 0; } httpPrepClientConn(hp->conn, 0); httpSetConnNotifier(hp->conn, httpEventChange); httpSetConnContext(hp->conn, hp); if (argc == 1 && ejsIs(ejs, argv[0], Null)) { hp->uri = httpUriToString(((EjsUri*) argv[0])->uri, HTTP_COMPLETE_URI); } hp->method = sclone("GET"); hp->requestContent = mprCreateBuf(BIT_MAX_BUFFER, -1); hp->responseContent = mprCreateBuf(BIT_MAX_BUFFER, -1); return hp; }
/* function reset(): Void */ static EjsObj *http_reset(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv) { httpResetCredentials(hp->conn); httpPrepClientConn(hp->conn, 0); return 0; }