]> granicus.if.org Git - apache/commitdiff
Tokenize the header while parsing it for the upgrade tokens and once the protocol...
authorBradley Nicholes <bnicholes@apache.org>
Tue, 13 Jul 2004 18:11:22 +0000 (18:11 +0000)
committerBradley Nicholes <bnicholes@apache.org>
Tue, 13 Jul 2004 18:11:22 +0000 (18:11 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@104273 13f79535-47bb-0310-9956-ffa450edef68

modules/ssl/ssl_engine_io.c
modules/ssl/ssl_engine_kernel.c

index 0d9779755545b7e3ca67b0c48ead978bb1068f04..d48292c50e6a5dfb845bc62a5ebacd62daf57142 100644 (file)
@@ -1170,7 +1170,7 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f,
 
 {
 #define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols"
-#define UPGRADE_HEADER "Upgrade: TLS/1.0 HTTP/1.1"
+#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1"
 #define CONNECTION_HEADER "Connection: Upgrade"
     const char *upgrade;
     const char *connection;
@@ -1178,6 +1178,9 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f,
     request_rec *r = f->r;
     SSLConnRec *sslconn;
     SSL *ssl;
+    char *token_string;
+    char *token;
+    char *token_state;
 
     /* Just remove the filter, if it doesn't work the first time, it won't
      * work at all for this request.
@@ -1192,19 +1195,30 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f,
     if (upgrade == NULL) {
         return ap_pass_brigade(f->next, bb);
     }
-    connection = apr_table_get(r->headers_in, "Connection");
+    token_string = apr_pstrdup(r->pool,upgrade);
+    token = apr_strtok(token_string,", ",&token_state);
+    while (token && strcmp(token,"TLS/1.0")) {
+        apr_strtok(NULL,", ",&token_state);
+    }
+    /* "Upgrade: TLS/1.0" header not found, don't do Upgrade */
+    if (!token) {
+        return ap_pass_brigade(f->next, bb);
+    }
 
-    apr_table_unset(r->headers_out, "Upgrade");
+    connection = apr_table_get(r->headers_in, "Connection");
 
-    /* XXX: I don't think the requirement that the client sends exactly 
-     * "Connection: Upgrade" is correct; the only requirement here is 
-     * on the client to send a  Connection header including the "upgrade" 
-     * token.
-     */
-    if (strcmp(connection, "Upgrade") || strcmp(upgrade, "TLS/1.0")) {
+    token_string = apr_pstrdup(r->pool,connection);
+    token = apr_strtok(token_string,",",&token_state);
+    while (token && strcmp(token,"Upgrade")) {
+        apr_strtok(NULL,",",&token_state);
+    }
+    /* "Connection: Upgrade" header not found, don't do Upgrade */
+    if (!token) {
         return ap_pass_brigade(f->next, bb);
     }
 
+    apr_table_unset(r->headers_out, "Upgrade");
+
     if (r->method_number == M_OPTIONS) {
         apr_bucket *b = NULL;
         /* This is a mandatory SSL upgrade. */
@@ -1238,18 +1252,22 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f,
      * However, this causes failures in perl-framework currently, 
      * perhaps pre-test if we have already negotiated?
      */
-    SSL_set_state(ssl, SSL_ST_ACCEPT);
+    SSL_set_accept_state(ssl);
     SSL_do_handshake(ssl);
 
     if (SSL_get_state(ssl) != SSL_ST_OK) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
-                     "Re-negotiation handshake failed: "
+                     "TLS Upgrade handshake failed: "
                 "Not accepted by client!?");
 
         return AP_FILTER_ERROR;
     }
 
-    return OK;
+    /* Now that we have initialized the ssl connection which added the ssl_io_filter, 
+       pass the brigade off to the connection based output filters so that the 
+       request can complete encrypted */
+    return ap_pass_brigade(f->c->output_filters, bb);
+
 }
 
 static apr_status_t ssl_io_filter_input(ap_filter_t *f,
index ccd84deed7fbcb89c470115daf3e171d646d72d6..6022ef92626ee830b01ba15ebcd5af60ea826e18 100644 (file)
@@ -1013,7 +1013,7 @@ int ssl_hook_Fixup(request_rec *r)
     SSL *ssl;
     int i;
 
-    if (sc->enabled == SSL_ENABLED_OPTIONAL) {
+    if (sc->enabled == SSL_ENABLED_OPTIONAL && !(sslconn && sslconn->ssl)) {
         apr_table_setn(r->headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
     }