* Do encryption stuff...
*/
+# if 0
if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
+#else
+ if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL, CUPSD_AUTH_NONE))
+ {
+ cupsdCloseClient(con);
+ return;
+ }
+# endif /* 0 */
+
if (!cupsdStartTLS(con))
{
cupsdCloseClient(con);
#endif /* HAVE_SSL */
}
+#if 0
if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
cupsdCloseClient(con);
return;
}
+#else
+ httpSetField(con->http, HTTP_FIELD_ALLOW,
+ "GET, HEAD, OPTIONS, POST, PUT");
+ httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
+
+ if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
+ {
+ cupsdCloseClient(con);
+ return;
+ }
+#endif /* 0 */
}
else if (!is_path_absolute(con->uri))
{
* Do encryption stuff...
*/
+# if 0
if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL,
CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
+# else
+ if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL,
+ CUPSD_AUTH_NONE))
+ {
+ cupsdCloseClient(con);
+ return;
+ }
+# endif /* 0 */
if (!cupsdStartTLS(con))
{
* Send 417-expectation-failed header...
*/
+ httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
+
if (!cupsdSendHeader(con, HTTP_STATUS_EXPECTATION_FAILED, NULL,
CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
-
- httpPrintf(con->http, "Content-Length: 0\r\n");
- httpPrintf(con->http, "\r\n");
-
- if (cupsdFlushHeader(con) < 0)
- {
- cupsdCloseClient(con);
- return;
- }
}
}
return;
}
+ cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND);
break;
}
}
return;
}
+ cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND);
break;
}
}
return;
}
- if (httpPrintf(con->http, "\r\n") < 0)
- {
- cupsdCloseClient(con);
- return;
- }
-
- if (cupsdFlushHeader(con) < 0)
- {
- cupsdCloseClient(con);
- return;
- }
-
-// con->http->state = HTTP_STATE_WAITING;
- DEBUG_puts("cupsdReadClient: Set state to HTTP_STATE_WAITING "
- "after HEAD.");
+ cupsdLogRequest(con, HTTP_STATUS_OK);
break;
}
return;
}
- if (httpPrintf(con->http, "\r\n") < 0)
- {
- cupsdCloseClient(con);
- return;
- }
-
- if (cupsdFlushHeader(con) < 0)
- {
- cupsdCloseClient(con);
- return;
- }
-
cupsdLogRequest(con, HTTP_STATUS_OK);
}
else if ((!strncmp(con->uri, "/admin/conf/", 12) &&
return;
}
+ cupsdLogRequest(con, HTTP_STATUS_FORBIDDEN);
break;
}
else if ((filename = get_file(con, &filestats, buf,
else
snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
- if (!cupsdSendHeader(con, HTTP_STATUS_OK, line, CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
-
- if (httpPrintf(con->http, "Last-Modified: %s\r\n",
- httpGetDateString(filestats.st_mtime)) < 0)
- {
- cupsdCloseClient(con);
- return;
- }
+ httpSetField(con->http, HTTP_FIELD_LAST_MODIFIED,
+ httpGetDateString(filestats.st_mtime));
+ httpSetLength(con->http, filestats.st_size);
- if (httpPrintf(con->http, "Content-Length: %lu\r\n",
- (unsigned long)filestats.st_size) < 0)
+ if (!cupsdSendHeader(con, HTTP_STATUS_OK, line, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
cupsdLogRequest(con, HTTP_STATUS_OK);
}
-
- if (httpPrintf(con->http, "\r\n") < 0)
- {
- cupsdCloseClient(con);
- return;
- }
-
- if (cupsdFlushHeader(con) < 0)
- {
- cupsdCloseClient(con);
- return;
- }
-
-// con->http->state = HTTP_STATE_WAITING;
- DEBUG_puts("cupsdReadClient: Set state to HTTP_STATE_WAITING "
- "after HEAD.");
break;
default :
else
fd = -1;
- con->pipe_pid = pipe_command(con, fd, &(con->file), command, options, root);
+ con->pipe_pid = pipe_command(con, fd, &(con->file), command, options, root);
+ con->pipe_status = HTTP_STATUS_OK;
if (fd >= 0)
close(fd);
if (code >= HTTP_STATUS_BAD_REQUEST && con->type != CUPSD_AUTH_NEGOTIATE)
httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF);
- /*
- * Send an error message back to the client. If the error code is a
- * 400 or 500 series, make sure the message contains some text, too!
- */
-
- if (!cupsdSendHeader(con, code, NULL, auth_type))
- return (0);
-
-#ifdef HAVE_SSL
- if (code == HTTP_STATUS_UPGRADE_REQUIRED)
- if (httpPrintf(con->http, "Connection: Upgrade\r\n") < 0)
- return (0);
-
- if (httpPrintf(con->http, "Upgrade: TLS/1.2,TLS/1.1,TLS/1.0\r\n") < 0)
- return (0);
-#endif /* HAVE_SSL */
-
if (httpGetVersion(con->http) >= HTTP_VERSION_1_1 &&
httpGetKeepAlive(con->http) == HTTP_KEEPALIVE_OFF)
- {
- if (httpPrintf(con->http, "Connection: close\r\n") < 0)
- return (0);
- }
+ httpSetField(con->http, HTTP_FIELD_CONNECTION, "close");
if (code >= HTTP_STATUS_BAD_REQUEST)
{
_httpStatus(con->language, code), redirect,
_httpStatus(con->language, code), text);
- if (httpPrintf(con->http, "Content-Type: text/html; charset=utf-8\r\n") < 0)
- return (0);
- if (httpPrintf(con->http, "Content-Length: %d\r\n",
- (int)strlen(message)) < 0)
- return (0);
- if (httpPrintf(con->http, "\r\n") < 0)
+ /*
+ * Send an error message back to the client. If the error code is a
+ * 400 or 500 series, make sure the message contains some text, too!
+ */
+
+ httpSetLength(con->http, strlen(message));
+
+ if (!cupsdSendHeader(con, code, "text/html", auth_type))
return (0);
+
if (httpPrintf(con->http, "%s", message) < 0)
return (0);
}
- else if (httpPrintf(con->http, "\r\n") < 0)
- return (0);
-
- if (cupsdFlushHeader(con) < 0)
- return (0);
-
-// con->http->state = HTTP_STATE_WAITING;
+ else
+ {
+ httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
- DEBUG_puts("cupsdSendError: Set state to HTTP_STATE_WAITING.");
+ if (!cupsdSendHeader(con, code, NULL, auth_type))
+ return (0);
+ }
return (1);
}
* 100-continue doesn't send any headers...
*/
- return (httpPrintf(con->http, "HTTP/%d.%d 100 Continue\r\n\r\n",
- httpGetVersion(con->http) / 100,
- httpGetVersion(con->http) % 100) > 0);
+ return (!httpWriteResponse(con->http, HTTP_STATUS_CONTINUE));
}
else if (code == HTTP_STATUS_CUPS_WEBIF_DISABLED)
{
code = HTTP_STATUS_OK;
}
- httpFlushWrite(con->http);
-
-// con->http->data_encoding = HTTP_ENCODING_FIELDS;
-
- if (httpPrintf(con->http, "HTTP/%d.%d %d %s\r\n", httpGetVersion(con->http) / 100,
- httpGetVersion(con->http) % 100, code, httpStatus(code)) < 0)
- return (0);
- if (httpPrintf(con->http, "Date: %s\r\n", httpGetDateString(time(NULL))) < 0)
- return (0);
if (ServerHeader)
- if (httpPrintf(con->http, "Server: %s\r\n", ServerHeader) < 0)
- return (0);
- if (httpGetKeepAlive(con->http) && httpGetVersion(con->http) >= HTTP_VERSION_1_0)
- {
- if (httpPrintf(con->http, "Connection: Keep-Alive\r\n") < 0)
- return (0);
- if (httpPrintf(con->http, "Keep-Alive: timeout=%d\r\n",
- KeepAliveTimeout) < 0)
- return (0);
- }
- else if (httpPrintf(con->http, "Connection: close\r\n") < 0)
- return (0);
+ httpSetField(con->http, HTTP_FIELD_SERVER, ServerHeader);
if (code == HTTP_STATUS_METHOD_NOT_ALLOWED)
- if (httpPrintf(con->http, "Allow: GET, HEAD, OPTIONS, POST, PUT\r\n") < 0)
- return (0);
+ httpSetField(con->http, HTTP_FIELD_ALLOW, "GET, HEAD, OPTIONS, POST, PUT");
if (code == HTTP_STATUS_UNAUTHORIZED)
{
{
cupsdLogClient(con, CUPSD_LOG_DEBUG, "WWW-Authenticate: %s", auth_str);
- if (httpPrintf(con->http, "WWW-Authenticate: %s\r\n", auth_str) < 0)
- return (0);
+ httpSetField(con->http, HTTP_FIELD_WWW_AUTHENTICATE, auth_str);
}
}
if (con->language && strcmp(con->language->language, "C"))
- {
- if (httpPrintf(con->http, "Content-Language: %s\r\n",
- con->language->language) < 0)
- return (0);
- }
+ httpSetField(con->http, HTTP_FIELD_CONTENT_LANGUAGE, con->language->language);
if (type)
{
if (!strcmp(type, "text/html"))
- {
- if (httpPrintf(con->http,
- "Content-Type: text/html; charset=utf-8\r\n") < 0)
- return (0);
- }
- else if (httpPrintf(con->http, "Content-Type: %s\r\n", type) < 0)
- return (0);
+ httpSetField(con->http, HTTP_FIELD_CONTENT_TYPE, "text/html; charset=utf-8");
+ else
+ httpSetField(con->http, HTTP_FIELD_CONTENT_TYPE, type);
}
- return (1);
+ return (!httpWriteResponse(con->http, code));
}
* Handle redirection and CGI status codes...
*/
- if (!_cups_strncasecmp(con->header, "Location:", 9))
+ http_field_t field; /* HTTP field */
+ char *value = strchr(con->header, ':');
+ /* Value of field */
+
+ if (value)
{
- if (!cupsdSendHeader(con, HTTP_STATUS_SEE_OTHER, NULL, CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
+ *value++ = '\0';
+ while (isspace(*value & 255))
+ value ++;
+ }
- con->sent_header = 2;
+ field = httpFieldValue(con->header);
- if (httpPrintf(con->http, "Content-Length: 0\r\n") < 0)
- return;
+ if (field != HTTP_FIELD_UNKNOWN && value)
+ {
+ httpSetField(con->http, field, value);
+
+ if (field == HTTP_FIELD_LOCATION)
+ {
+ con->pipe_status = HTTP_STATUS_SEE_OTHER;
+ con->sent_header = 2;
+ }
+ else
+ con->sent_header = 1;
}
- else if (!_cups_strncasecmp(con->header, "Status:", 7))
+ else if (!_cups_strcasecmp(con->header, "Status") && value)
{
- cupsdSendError(con, (http_status_t)atoi(con->header + 7),
- CUPSD_AUTH_NONE);
+ con->pipe_status = (http_status_t)atoi(value);
con->sent_header = 2;
}
- else
+ else if (!_cups_strcasecmp(con->header, "Set-Cookie") && value)
{
- if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
+ char *sep = strchr(value, ';');
+ /* Separator between name=value and the rest */
- con->sent_header = 1;
+ if (sep)
+ *sep = '\0';
- if (httpGetVersion(con->http) == HTTP_VERSION_1_1)
- {
- if (httpPrintf(con->http, "Transfer-Encoding: chunked\r\n") < 0)
- return;
- }
- }
+ httpSetCookie(con->http, value);
+ con->sent_header = 1;
+ }
}
- if (_cups_strncasecmp(con->header, "Status:", 7))
- httpPrintf(con->http, "%s\r\n", con->header);
-
/*
* Update buffer...
*/
{
con->got_fields = 1;
- if (cupsdFlushHeader(con) < 0)
+ if (httpGetVersion(con->http) == HTTP_VERSION_1_1 &&
+ !httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0])
+ httpSetLength(con->http, 0);
+
+ if (!cupsdSendHeader(con, con->pipe_status, NULL, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
-
- if (httpGetVersion(con->http) == HTTP_VERSION_1_1)
- httpSetLength(con->http, 0);
-// con->http->data_encoding = HTTP_ENCODING_CHUNKED;
}
else
field_col = 0;
}
if (!con->got_fields)
- {
-// con->http->activity = time(NULL);
return;
- }
}
if (con->header_used > 0)
}
}
-// con->http->state = HTTP_STATE_WAITING;
-
cupsdAddSelect(httpGetFd(con->http), (cupsd_selfunc_t)cupsdReadClient, NULL, con);
cupsdLogClient(con, CUPSD_LOG_DEBUG, "Waiting for request.");
cupsdSetBusyState();
}
}
-
-// con->http->activity = time(NULL);
}
con->pipe_pid = 0;
- if (!cupsdSendHeader(con, code, type, CUPSD_AUTH_NONE))
- return (0);
+ httpSetLength(con->http, filestats->st_size);
- if (httpPrintf(con->http, "Last-Modified: %s\r\n",
- httpGetDateString(filestats->st_mtime)) < 0)
- return (0);
- if (httpPrintf(con->http, "Content-Length: " CUPS_LLFMT "\r\n",
- CUPS_LLCAST filestats->st_size) < 0)
- return (0);
- if (httpPrintf(con->http, "\r\n") < 0)
- return (0);
+ httpSetField(con->http, HTTP_FIELD_LAST_MODIFIED,
+ httpGetDateString(filestats->st_mtime));
- if (cupsdFlushHeader(con) < 0)
+ if (!cupsdSendHeader(con, code, type, CUPSD_AUTH_NONE))
return (0);
- httpSetLength(con->http, filestats->st_size);
-
cupsdAddSelect(httpGetFd(con->http), (cupsd_selfunc_t)cupsdReadClient,
(cupsd_selfunc_t)cupsdWriteClient, con);
uri ? uri->values[0].string.text : "no URI",
con->http->hostname);
- if (cupsdSendHeader(con, HTTP_OK, "application/ipp", CUPSD_AUTH_NONE))
- {
#ifdef CUPSD_USE_CHUNKING
- /*
- * Because older versions of CUPS (1.1.17 and older) and some IPP
- * clients do not implement chunking properly, we cannot use
- * chunking by default. This may become the default in future
- * CUPS releases, or we might add a configuration directive for
- * it.
- */
-
- if (con->http->version == HTTP_1_1)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Transfer-Encoding: chunked",
- con->number);
-
- if (httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n\r\n") < 0)
- return (0);
+ /*
+ * Because older versions of CUPS (1.1.17 and older) and some IPP
+ * clients do not implement chunking properly, we cannot use
+ * chunking by default. This may become the default in future
+ * CUPS releases, or we might add a configuration directive for
+ * it.
+ */
- if (cupsdFlushHeader(con) < 0)
- return (0);
+ if (con->http->version == HTTP_1_1)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "[Client %d] Transfer-Encoding: chunked",
+ con->number);
- con->http->data_encoding = HTTP_ENCODE_CHUNKED;
- }
- else
+ cupsdSetLength(con->http, 0);
+ }
+ else
#endif /* CUPSD_USE_CHUNKING */
- {
- size_t length; /* Length of response */
-
-
- length = ippLength(con->response);
-
- if (con->file >= 0 && !con->pipe_pid)
- {
- struct stat fileinfo; /* File information */
-
- if (!fstat(con->file, &fileinfo))
- length += fileinfo.st_size;
- }
+ {
+ size_t length; /* Length of response */
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Content-Length: " CUPS_LLFMT,
- con->number, CUPS_LLCAST length);
- if (httpPrintf(HTTP(con), "Content-Length: " CUPS_LLFMT "\r\n\r\n",
- CUPS_LLCAST length) < 0)
- return (0);
- if (cupsdFlushHeader(con) < 0)
- return (0);
+ length = ippLength(con->response);
- con->http->data_encoding = HTTP_ENCODE_LENGTH;
- con->http->data_remaining = length;
+ if (con->file >= 0 && !con->pipe_pid)
+ {
+ struct stat fileinfo; /* File information */
- if (con->http->data_remaining <= INT_MAX)
- con->http->_data_remaining = con->http->data_remaining;
- else
- con->http->_data_remaining = INT_MAX;
+ if (!fstat(con->file, &fileinfo))
+ length += fileinfo.st_size;
}
- cupsdAddSelect(httpGetFd(con->http), (cupsd_selfunc_t)cupsdReadClient,
- (cupsd_selfunc_t)cupsdWriteClient, con);
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "[Client %d] Content-Length: " CUPS_LLFMT,
+ con->number, CUPS_LLCAST length);
+ httpSetLength(con->http, length);
+ }
+ if (cupsdSendHeader(con, HTTP_OK, "application/ipp", CUPSD_AUTH_NONE))
+ {
/*
* Tell the caller the response header was sent successfully...
*/
+ cupsdAddSelect(httpGetFd(con->http), (cupsd_selfunc_t)cupsdReadClient,
+ (cupsd_selfunc_t)cupsdWriteClient, con);
+
return (1);
}
else