Index: cgi-bin/libcupscgi.exp =================================================================== --- cgi-bin/libcupscgi.exp (revision 8235) +++ cgi-bin/libcupscgi.exp (working copy) @@ -30,6 +30,7 @@ _cgiShowJobs _cgiStartHTML _cgiStartMultipart +_cgiSupportsMultipart _cgiText _helpDeleteIndex _helpFindNode Index: cgi-bin/html.c =================================================================== --- cgi-bin/html.c (revision 8235) +++ cgi-bin/html.c (working copy) @@ -3,7 +3,7 @@ * * HTML support functions for the Common UNIX Printing System (CUPS). * - * Copyright 2007-2008 by Apple Inc. + * Copyright 2007-2009 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -14,12 +14,13 @@ * * Contents: * - * cgiEndHTML() - End a HTML page. - * cgiEndMultipart() - End the delivery of a multipart web page. - * cgiFormEncode() - Encode a string as a form variable... - * cgiStartHTML() - Start a HTML page. - * cgiStartMultipart() - Start a multipart delivery of a web page... - * cgi_null_passwd() - Return a NULL password for authentication. + * cgiEndHTML() - End a HTML page. + * cgiEndMultipart() - End the delivery of a multipart web page. + * cgiFormEncode() - Encode a string as a form variable. + * cgiStartHTML() - Start a HTML page. + * cgiStartMultipart() - Start a multipart delivery of a web page. + * cgiSupportsMultipart() - Does the browser support multi-part documents? + * cgi_null_passwd() - Return a NULL password for authentication. */ /* @@ -72,7 +73,7 @@ /* - * 'cgiFormEncode()' - Encode a string as a form variable... + * 'cgiFormEncode()' - Encode a string as a form variable. */ char * /* O - Destination string */ @@ -183,7 +184,7 @@ /* - * 'cgiStartMultipart()' - Start a multipart delivery of a web page... + * 'cgiStartMultipart()' - Start a multipart delivery of a web page. */ void @@ -196,6 +197,41 @@ /* + * 'cgiSupportsMultipart()' - Does the browser support multi-part documents? + */ + +int /* O - 1 if multi-part supported, 0 otherwise */ +cgiSupportsMultipart(void) +{ + const char *user_agent; /* User-Agent string */ + static int supports_multipart = -1;/* Cached value */ + + + if (supports_multipart < 0) + { + /* + * CUPS STR #3049: Apparently some browsers don't support multi-part + * documents, which makes them useless for many web sites. Rather than + * abandoning those users, we'll offer a degraded single-part mode... + * + * Currently we know that anything based on Gecko, MSIE, and Safari all + * work. We'll add more as they are reported/tested. + */ + + if ((user_agent = getenv("HTTP_USER_AGENT")) != NULL && + (strstr(user_agent, " Gecko/") != NULL || + strstr(user_agent, " MSIE ") != NULL || + strstr(user_agent, " Safari/") != NULL)) + supports_multipart = 1; + else + supports_multipart = 0; + } + + return (supports_multipart); +} + + +/* * 'cgi_null_passwd()' - Return a NULL password for authentication. */ Index: cgi-bin/cgi.h =================================================================== --- cgi-bin/cgi.h (revision 8235) +++ cgi-bin/cgi.h (working copy) @@ -3,7 +3,7 @@ * * CGI support library definitions. * - * Copyright 2007-2008 by Apple Inc. + * Copyright 2007-2009 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -95,6 +95,7 @@ extern void cgiShowJobs(http_t *http, const char *dest); extern void cgiStartHTML(const char *title); extern void cgiStartMultipart(void); +extern int cgiSupportsMultipart(void); extern const char *cgiText(const char *message); #endif /* !_CUPS_CGI_H_ */ Index: cgi-bin/ipp-var.c =================================================================== --- cgi-bin/ipp-var.c (revision 8235) +++ cgi-bin/ipp-var.c (working copy) @@ -3,7 +3,7 @@ * * CGI <-> IPP variable routines for the Common UNIX Printing System (CUPS). * - * Copyright 2007-2008 by Apple Inc. + * Copyright 2007-2009 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -548,11 +548,14 @@ * Show status... */ - cgiStartMultipart(); - cgiStartHTML(title); - cgiCopyTemplateLang("command.tmpl"); - cgiEndHTML(); - fflush(stdout); + if (cgiSupportsMultipart()) + { + cgiStartMultipart(); + cgiStartHTML(title); + cgiCopyTemplateLang("command.tmpl"); + cgiEndHTML(); + fflush(stdout); + } /* * Send the command file job... @@ -574,7 +577,9 @@ cgiStartHTML(title); cgiCopyTemplateLang("error.tmpl"); cgiEndHTML(); - cgiEndMultipart(); + + if (cgiSupportsMultipart()) + cgiEndMultipart(); return; } @@ -592,8 +597,10 @@ cgiStartHTML(title); cgiCopyTemplateLang("error.tmpl"); cgiEndHTML(); - cgiEndMultipart(); + if (cgiSupportsMultipart()) + cgiEndMultipart(); + cupsCancelJob(dest, job_id); return; } @@ -602,44 +609,47 @@ * Wait for the job to complete... */ - for (;;) + if (cgiSupportsMultipart()) { - /* - * Get the current job state... - */ + for (;;) + { + /* + * Get the current job state... + */ - snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); - request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", - NULL, uri); - if (user) - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, - "requesting-user-name", NULL, user); - ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, - "requested-attributes", 2, NULL, job_attrs); + snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); + request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", + NULL, uri); + if (user) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", 2, NULL, job_attrs); - if ((response = cupsDoRequest(http, request, "/")) != NULL) - cgiSetIPPVars(response, NULL, NULL, NULL, 0); + if ((response = cupsDoRequest(http, request, "/")) != NULL) + cgiSetIPPVars(response, NULL, NULL, NULL, 0); - attr = ippFindAttribute(response, "job-state", IPP_TAG_ENUM); - if (!attr || attr->values[0].integer >= IPP_JOB_STOPPED) - { - ippDelete(response); - break; - } + attr = ippFindAttribute(response, "job-state", IPP_TAG_ENUM); + if (!attr || attr->values[0].integer >= IPP_JOB_STOPPED) + { + ippDelete(response); + break; + } - /* - * Job not complete, so update the status... - */ + /* + * Job not complete, so update the status... + */ - ippDelete(response); + ippDelete(response); - cgiStartHTML(title); - cgiCopyTemplateLang("command.tmpl"); - cgiEndHTML(); - fflush(stdout); + cgiStartHTML(title); + cgiCopyTemplateLang("command.tmpl"); + cgiEndHTML(); + fflush(stdout); - sleep(5); + sleep(5); + } } /* @@ -655,7 +665,9 @@ cgiStartHTML(title); cgiCopyTemplateLang("command.tmpl"); cgiEndHTML(); - cgiEndMultipart(); + + if (cgiSupportsMultipart()) + cgiEndMultipart(); } Index: cgi-bin/admin.c =================================================================== --- cgi-bin/admin.c (revision 8235) +++ cgi-bin/admin.c (working copy) @@ -3,7 +3,7 @@ * * Administration CGI for the Common UNIX Printing System (CUPS). * - * Copyright 2007-2008 by Apple Inc. + * Copyright 2007-2009 by Apple Inc. * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -261,7 +261,7 @@ current_device ++; - if (time(NULL) > last_device_time) + if (time(NULL) > last_device_time && cgiSupportsMultipart()) { /* * Update the page... @@ -921,7 +921,21 @@ if (cupsGetDevices(http, 30, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE, (cups_device_cb_t)choose_device_cb, (void *)title) == IPP_OK) + { fputs("DEBUG: Got device list!\n", stderr); + + if (!cgiSupportsMultipart()) + { + /* + * Non-modern browsers that don't support multi-part documents get + * everything at the end... + */ + + cgiStartHTML(title); + cgiCopyTemplateLang("choose-device.tmpl"); + cgiEndHTML(); + } + } else { fprintf(stderr,