* cupsdUpdateCGI() - Read status messages from CGI scripts and programs.
* cupsdWriteClient() - Write data to a client as needed.
* check_if_modified() - Decode an "If-Modified-Since" line.
+ * compare_clients() - Compare two client connections.
* encrypt_client() - Enable encryption for the client...
* get_cdsa_certificate() - Convert a keychain name into the CFArrayRef
* required by SSLSetCertificate.
static int check_if_modified(cupsd_client_t *con,
struct stat *filestats);
+static int compare_clients(cupsd_client_t *a, cupsd_client_t *b,
+ void *data);
#ifdef HAVE_SSL
static int encrypt_client(cupsd_client_t *con);
#endif /* HAVE_SSL */
if (!Clients)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for client array!");
+ "Unable to allocate memory for clients array!");
+ cupsdPauseListening();
+ return;
+ }
+
+ if (!ActiveClients)
+ ActiveClients = cupsArrayNew((cups_array_func_t)compare_clients, NULL);
+
+ if (!ActiveClients)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to allocate memory for active clients array!");
cupsdPauseListening();
return;
}
switch (SSL_shutdown(conn))
{
case 1 :
- cupsdLogMessage(CUPSD_LOG_INFO,
- "cupsdCloseClient: SSL shutdown successful!");
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "SSL shutdown successful!");
break;
case -1 :
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdCloseClient: Fatal error during SSL shutdown!");
+ "Fatal error during SSL shutdown!");
default :
while ((error = ERR_get_error()) != 0)
- cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdCloseClient: %s",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "SSL shutdown failed: %s",
ERR_error_string(error, NULL));
break;
}
switch (error)
{
case GNUTLS_E_SUCCESS:
- cupsdLogMessage(CUPSD_LOG_INFO,
- "cupsdCloseClient: SSL shutdown successful!");
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "SSL shutdown successful!");
break;
default:
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdCloseClient: %s", gnutls_strerror(error));
+ "SSL shutdown failed: %s", gnutls_strerror(error));
break;
}
* Close the socket and clear the file from the input set for select()...
*/
- if (con->http.fd > 0)
+ if (con->http.fd >= 0)
{
+ cupsArrayRemove(ActiveClients, con);
+ cupsdSetBusyState();
+
if (partial)
{
/*
switch (sscanf(line, "%63s%1023s%63s", operation, con->uri, version))
{
case 1 :
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Bad request line \"%s\" from %s!", line,
- con->http.hostname);
- cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
- cupsdCloseClient(con);
+ if (line[0])
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Bad request line \"%s\" from %s!", line,
+ con->http.hostname);
+ cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
+ cupsdCloseClient(con);
+ }
return;
case 2 :
con->http.version = HTTP_0_9;
con->http.status = HTTP_OK;
+ cupsArrayAdd(ActiveClients, con);
+ cupsdSetBusyState();
+
case HTTP_OPTIONS :
case HTTP_DELETE :
case HTTP_GET :
break; /* Anti-compiler-warning-code */
}
- if (!con->http.keep_alive && con->http.state == HTTP_WAITING)
- cupsdCloseClient(con);
+ if (con->http.state == HTTP_WAITING)
+ {
+ if (!con->http.keep_alive)
+ cupsdCloseClient(con);
+ else
+ {
+ cupsArrayRemove(ActiveClients, con);
+ cupsdSetBusyState();
+ }
+ }
}
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"cupsdWriteClient(con=%p) %d response=%p(%d), file=%d "
"pipe_pid=%d state=%d",
- con, con->http.fd, con->response, con->response->state,
+ con, con->http.fd, con->response,
+ con->response ? con->response->state : -1,
con->file, con->pipe_pid, con->http.state);
#endif /* DEBUG */
return;
}
else if (bytes == 0)
+ {
con->http.activity = time(NULL);
+ return;
+ }
}
if (bytes > 0)
return;
}
+ if (con->http.data_encoding == HTTP_ENCODE_CHUNKED)
+ httpFlushWrite(HTTP(con));
+
con->bytes += bytes;
if (con->http.state == HTTP_WAITING)
}
+/*
+ * 'compare_clients()' - Compare two client connections.
+ */
+
+static int /* O - Result of comparison */
+compare_clients(cupsd_client_t *a, /* I - First client */
+ cupsd_client_t *b, /* I - Second client */
+ void *data) /* I - User data (not used) */
+{
+ (void)data;
+
+ if (a == b)
+ return (0);
+ else if (a < b)
+ return (-1);
+ else
+ return (1);
+}
+
+
#ifdef HAVE_SSL
/*
* 'encrypt_client()' - Enable encryption for the client...
if ((options = strchr(con->uri, '?')) != NULL)
{
options ++;
-
- if (strchr(options, '='))
- cupsdSetStringf(&(con->query_string), "QUERY_STRING=%s", options);
+ cupsdSetStringf(&(con->query_string), "QUERY_STRING=%s", options);
}
/*
filename = strrchr(filename, '/') + 1; /* Filename always absolute */
- cupsdSetString(&con->options, options);
+ if (options)
+ cupsdSetStringf(&con->options, " %s", options);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"is_cgi: Returning 1 with command=\"%s\" and options=\"%s\"",
envp[envc ++] = con->query_string;
}
+ else
+ envp[envc ++] = "QUERY_STRING=";
}
else
{