diff --git a/lib/http.c b/lib/http.c
index a1eef81..db2d91c 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -2350,6 +2350,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
     if(result)
       return result;
   }
+  else if((ptr=Curl_checkheaders(conn, "Upgrade:"))) {
+    if(Curl_compareheader(ptr, "Upgrade:", "websocket")) {
+      data->req.upgr101 = UPGR101_WS_REQUESTED;
+    }
+  }
 
 #if !defined(CURL_DISABLE_COOKIES)
   if(data->cookies || addcookies) {
@@ -2942,6 +2947,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
 {
   CURLcode result;
   struct SingleRequest *k = &data->req;
+  const char *ptr;
 
   /* header line within buffer loop */
   do {
@@ -3035,16 +3041,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
 #endif /* CURL_DOES_CONVERSIONS */
 
       if(100 <= k->httpcode && 199 >= k->httpcode) {
-        /*
-         * We have made a HTTP PUT or POST and this is 1.1-lingo
-         * that tells us that the server is OK with this and ready
-         * to receive the data.
-         * However, we'll get more headers now so we must get
-         * back into the header-parsing state!
-         */
-        k->header = TRUE;
-        k->headerline = 0; /* restart the header line counter */
-
         /* "A user agent MAY ignore unexpected 1xx status responses." */
         switch(k->httpcode) {
         case 100:
@@ -3056,10 +3052,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
           break;
         case 101:
           /* Switching Protocols */
-          if(k->upgr101 == UPGR101_REQUESTED) {
-            infof(data, "Received 101\n");
-            k->upgr101 = UPGR101_RECEIVED;
-
+          infof(data, "Received 101\n");
+          if(k->upgr101 == UPGR101_H2_REQUESTED) {
+            k->upgr101 = UPGR101_H2_RECEIVED;
             /* switch to http2 now. The bytes after response headers
                are also processed here, otherwise they are lost. */
             result = Curl_http2_switched(conn, k->str, *nread);
@@ -3067,8 +3062,28 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
               return result;
             *nread = 0;
           }
+          else if(k->upgr101 == UPGR101_WS_REQUESTED) {
+            k->upgr101 = UPGR101_WS_RECEIVED;
+            ptr = Curl_checkheaders(conn, "Upgrade");
+            if(ptr && Curl_compareheader(ptr, "Upgrade:", "websocket")) {
+              infof(data, "Upgrade: Websocket\n");
+              k->header = FALSE;
+              k->keepon |= KEEP_SEND | KEEP_RECV;
+              conn->writesockfd = conn->sockfd;
+              connclose(conn, "close after websocket communication");
+            }
+          }
           break;
         default:
+          /*
+           * We have made a HTTP PUT or POST and this is 1.1-lingo
+           * that tells us that the server is OK with this and ready
+           * to receive the data.
+           * However, we'll get more headers now so we must get
+           * back into the header-parsing state!
+           */
+          k->header = TRUE;
+          k->headerline = 0; /* restart the header line counter */
           break;
         }
       }
@@ -3296,7 +3311,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
         if(nc==3) {
           conn->httpversion += 10 * httpversion_major;
 
-          if(k->upgr101 == UPGR101_RECEIVED) {
+          if(k->upgr101 == UPGR101_H2_RECEIVED) {
             /* supposedly upgraded to http2 now */
             if(conn->httpversion != 20)
               infof(data, "Lying server, not serving HTTP/2\n");
@@ -3379,7 +3394,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
           connclose(conn, "HTTP/1.0 close after body");
         }
         else if(conn->httpversion == 20 ||
-                (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
+                (k->upgr101 == UPGR101_H2_REQUESTED && k->httpcode == 101)) {
           DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
 
           /* HTTP/2 cannot blacklist multiplexing since it is a core
@@ -3627,7 +3642,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
          The forth means the requested range was unsatisfied.
       */
 
-      char *ptr = k->p + 14;
+      ptr = k->p + 14;
 
       /* Move forward until first digit or asterisk */
       while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
diff --git a/lib/http2.c b/lib/http2.c
index 1a2c486..5392484 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -977,7 +977,7 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
                             NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
   free(base64);
 
-  k->upgr101 = UPGR101_REQUESTED;
+  k->upgr101 = UPGR101_H2_REQUESTED;
 
   return result;
 }
@@ -1483,7 +1483,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
   conn->recv[FIRSTSOCKET] = http2_recv;
   conn->send[FIRSTSOCKET] = http2_send;
 
-  if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
+  if(conn->data->req.upgr101 == UPGR101_H2_RECEIVED) {
     /* stream 1 is opened implicitly on upgrade */
     stream->stream_id = 1;
     /* queue SETTINGS frame (again) */
diff --git a/lib/transfer.c b/lib/transfer.c
index 718139b..0b3b07d 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -802,7 +802,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
        may now close the connection. If there's now any kind of sending going
        on from our side, we need to stop that immediately. */
     infof(data, "we are done reading and this is set to close, stop send\n");
-    k->keepon &= ~KEEP_SEND; /* no writing anymore either */
+    k->keepon &= ~(KEEP_SEND|KEEP_SEND_PAUSE); /* no writing anymore either */
   }
 
   return CURLE_OK;
diff --git a/lib/urldata.h b/lib/urldata.h
index b1c2056..493d607 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -598,9 +598,10 @@ enum expect100 {
 
 enum upgrade101 {
   UPGR101_INIT,               /* default state */
-  UPGR101_REQUESTED,          /* upgrade requested */
-  UPGR101_RECEIVED,           /* response received */
-  UPGR101_WORKING             /* talking upgraded protocol */
+  UPGR101_H2_REQUESTED,       /* upgrade HTTP2 requested */
+  UPGR101_H2_RECEIVED,        /* upgrade HTTP2 received */
+  UPGR101_WS_REQUESTED,       /* upgrade WebSocket requested */
+  UPGR101_WS_RECEIVED         /* upgrade WebSocket received */
 };
 
 /*

