@@ -272,101 +272,6 @@ bool isPowerOfTwo(int n)
272272 return (n != 0 ) && (n & (n - 1 )) == 0 ;
273273}
274274
275- bool parseHttpHeader (CirBuf &buf, std::string &websocket_key, int &websocket_version, std::string &subprotocol, std::string &xRealIp)
276- {
277- std::vector<char > buf_data = buf.peekAllToVector ();
278-
279- const std::string s (buf_data.data (), buf_data.size ());
280- std::istringstream is (s);
281- bool doubleEmptyLine = false ; // meaning, the HTTP header is complete
282- bool upgradeHeaderSeen = false ;
283- bool connectionHeaderSeen = false ;
284- bool firstLine = true ;
285- bool subprotocol_seen = false ;
286-
287- std::string line;
288- while (std::getline (is, line))
289- {
290- trim (line);
291- if (firstLine)
292- {
293- firstLine = false ;
294- if (!startsWith (line, " GET" ))
295- throw BadHttpRequest (" Websocket request should start with GET." );
296- continue ;
297- }
298- if (line.empty ())
299- {
300- doubleEmptyLine = true ;
301- break ;
302- }
303-
304- std::list<std::string> fields = split (line, ' :' , 1 );
305-
306- if (fields.size () != 2 )
307- {
308- throw BadHttpRequest (" This does not look like a HTTP request." );
309- }
310-
311- const std::vector<std::string> fields2 (fields.begin (), fields.end ());
312- std::string name = str_tolower (fields2[0 ]);
313- trim (name);
314- std::string value = fields2[1 ];
315- trim (value);
316- std::string value_lower = str_tolower (value);
317-
318- if (name == " upgrade" )
319- {
320- std::vector<std::string> protocols = splitToVector (value_lower, ' ,' );
321- for (std::string &prot : protocols)
322- {
323- trim (prot);
324-
325- if (prot == " websocket" )
326- {
327- upgradeHeaderSeen = true ;
328- }
329- }
330- }
331- else if (name == " connection" && strContains (value_lower, " upgrade" ))
332- connectionHeaderSeen = true ;
333- else if (name == " sec-websocket-key" )
334- websocket_key = value;
335- else if (name == " sec-websocket-version" )
336- websocket_version = stoi (value);
337- else if (name == " sec-websocket-protocol" && strContains (value_lower, " mqtt" ))
338- {
339- std::vector<std::string> protocols = splitToVector (value, ' ,' );
340-
341- for (std::string &prot : protocols)
342- {
343- trim (prot);
344-
345- // Return what is requested, which can be 'mqttv3.1' or 'mqtt', or whatever variant.
346- if (strContains (str_tolower (prot), " mqtt" ))
347- {
348- subprotocol = prot;
349- subprotocol_seen = true ;
350- }
351- }
352- }
353- else if (name == " x-real-ip" && value.length () < 64 )
354- {
355- xRealIp = value;
356- }
357- }
358-
359- if (doubleEmptyLine)
360- {
361- if (!connectionHeaderSeen || !upgradeHeaderSeen)
362- throw BadHttpRequest (" HTTP request is not a websocket upgrade request." );
363- if (!subprotocol_seen)
364- throw BadHttpRequest (" HTTP header Sec-WebSocket-Protocol with value 'mqtt' must be present." );
365- }
366-
367- return doubleEmptyLine;
368- }
369-
370275std::vector<char > base64Decode (const std::string &s)
371276{
372277 if (s.length () % 4 != 0 )
@@ -405,58 +310,6 @@ std::string base64Encode(const unsigned char *input, const int length)
405310 return result;
406311}
407312
408- std::string generateWebsocketAcceptString (const std::string &websocketKey)
409- {
410- unsigned char md_value[EVP_MAX_MD_SIZE];
411- unsigned int md_len;
412-
413- EVP_MD_CTX *mdctx = EVP_MD_CTX_new ();;
414- const EVP_MD *md = EVP_sha1 ();
415- EVP_DigestInit_ex (mdctx, md, NULL );
416-
417- const std::string keyPlusMagic = websocketKey + " 258EAFA5-E914-47DA-95CA-C5AB0DC85B11" ;
418-
419- EVP_DigestUpdate (mdctx, keyPlusMagic.c_str (), keyPlusMagic.length ());
420- EVP_DigestFinal_ex (mdctx, md_value, &md_len);
421- EVP_MD_CTX_free (mdctx);
422-
423- std::string base64 = base64Encode (md_value, md_len);
424- return base64;
425- }
426-
427- std::string generateInvalidWebsocketVersionHttpHeaders (const int wantedVersion)
428- {
429- std::ostringstream oss;
430- oss << " HTTP/1.1 400 Bad Request\r\n " ;
431- oss << " Sec-WebSocket-Version: " << wantedVersion;
432- oss << " \r\n " ;
433- oss.flush ();
434- return oss.str ();
435- }
436-
437- std::string generateBadHttpRequestReponse (const std::string &msg)
438- {
439- std::ostringstream oss;
440- oss << " HTTP/1.1 400 Bad Request\r\n " ;
441- oss << " \r\n " ;
442- oss << msg;
443- oss.flush ();
444- return oss.str ();
445- }
446-
447- std::string generateWebsocketAnswer (const std::string &acceptString, const std::string &subprotocol)
448- {
449- std::ostringstream oss;
450- oss << " HTTP/1.1 101 Switching Protocols\r\n " ;
451- oss << " Upgrade: websocket\r\n " ;
452- oss << " Connection: Upgrade\r\n " ;
453- oss << " Sec-WebSocket-Accept: " << acceptString << " \r\n " ;
454- oss << " Sec-WebSocket-Protocol: " << subprotocol << " \r\n " ;
455- oss << " \r\n " ;
456- oss.flush ();
457- return oss.str ();
458- }
459-
460313// Using a separate ssl context to test, because it's the easiest way to load certs and key atomitcally.
461314void testSsl (const std::string &fullchain, const std::string &privkey)
462315{
@@ -628,18 +481,6 @@ std::string sockaddrToString(const sockaddr *addr)
628481 return " [unknown address]" ;
629482}
630483
631- std::string websocketCloseCodeToString (uint16_t code)
632- {
633- switch (code) {
634- case 1000 :
635- return " Normal websocket close" ;
636- case 1001 :
637- return " Browser navigating away from page" ;
638- default :
639- return formatString (" Websocket status code %d" , code);
640- }
641- }
642-
643484std::string protocolVersionString (ProtocolVersion p)
644485{
645486 switch (p)
0 commit comments