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; }
static void cacheAtClient(HttpConn *conn) { HttpTx *tx; HttpCache *cache; cchar *value; tx = conn->tx; cache = conn->tx->cache; if (!mprLookupKey(tx->headers, "Cache-Control")) { if ((value = mprLookupKey(conn->tx->headers, "Cache-Control")) != 0) { if (strstr(value, "max-age") == 0) { httpAppendHeader(conn, "Cache-Control", "max-age=%d", cache->clientLifespan / MPR_TICKS_PER_SEC); } } else { httpAddHeader(conn, "Cache-Control", "max-age=%d", cache->clientLifespan / MPR_TICKS_PER_SEC); } #if UNUSED && KEEP { /* Old HTTP/1.0 clients don't understand Cache-Control */ struct tm tm; mprDecodeUniversalTime(&tm, conn->http->now + (expires * MPR_TICKS_PER_SEC)); httpAddHeader(conn, "Expires", "%s", mprFormatTime(MPR_HTTP_DATE, &tm)); } #endif } }
/* Set lifespan < 0 to delete the cookie in the client. Set lifespan == 0 for no expiry. WARNING: Some browsers (Chrome, Firefox) do not delete session cookies when you exit the browser. */ PUBLIC void httpSetCookie(HttpConn *conn, cchar *name, cchar *value, cchar *path, cchar *cookieDomain, MprTicks lifespan, int flags) { HttpRx *rx; char *cp, *expiresAtt, *expires, *domainAtt, *domain, *secure, *httponly; rx = conn->rx; if (path == 0) { path = "/"; } domain = (char*) cookieDomain; if (!domain) { domain = sclone(rx->hostHeader); if ((cp = strchr(domain, ':')) != 0) { *cp = '\0'; } if (*domain && domain[strlen(domain) - 1] == '.') { domain[strlen(domain) - 1] = '\0'; } } domainAtt = domain ? "; domain=" : ""; if (domain && !strchr(domain, '.')) { if (smatch(domain, "localhost")) { domainAtt = domain = ""; } else { domain = sjoin(".", domain, NULL); } } if (lifespan) { expiresAtt = "; expires="; expires = mprFormatUniversalTime(MPR_HTTP_DATE, mprGetTime() + lifespan); } else { expires = expiresAtt = ""; } secure = (conn->secure & (flags & HTTP_COOKIE_SECURE)) ? "; secure" : ""; httponly = (flags & HTTP_COOKIE_HTTP) ? "; httponly" : ""; /* Allow multiple cookie headers. Even if the same name. Later definitions take precedence. */ httpAppendHeader(conn, "Set-Cookie", sjoin(name, "=", value, "; path=", path, domainAtt, domain, expiresAtt, expires, secure, httponly, NULL)); httpAppendHeader(conn, "Cache-Control", "no-cache=\"set-cookie\""); }