Browse Source

Basic framework of HTTP server is there.

Adam Ierymenko 10 years ago
parent
commit
5c1262f324
1 changed files with 61 additions and 4 deletions
  1. 61 4
      service/One.cpp

+ 61 - 4
service/One.cpp

@@ -95,6 +95,7 @@ struct HttpConnection
 	bool shouldKeepAlive;
 	bool shouldKeepAlive;
 	OneImpl *parent;
 	OneImpl *parent;
 	PhySocket *sock;
 	PhySocket *sock;
+	InetAddress from;
 	http_parser parser;
 	http_parser parser;
 	unsigned long messageSize;
 	unsigned long messageSize;
 	unsigned long writePtr;
 	unsigned long writePtr;
@@ -219,6 +220,11 @@ public:
 			_fatalErrorMessage = "unexpected exception in main thread";
 			_fatalErrorMessage = "unexpected exception in main thread";
 		}
 		}
 
 
+		try {
+			while (!_httpConnections.empty())
+				_phy.close(_httpConnections.begin()->first);
+		} catch ( ... ) {}
+
 		delete _node;
 		delete _node;
 		_node = (Node *)0;
 		_node = (Node *)0;
 
 
@@ -279,6 +285,7 @@ public:
 		htc->shouldKeepAlive = true;
 		htc->shouldKeepAlive = true;
 		htc->parent = this;
 		htc->parent = this;
 		htc->sock = sockN;
 		htc->sock = sockN;
+		htc->from = from;
 		http_parser_init(&(htc->parser),HTTP_REQUEST);
 		http_parser_init(&(htc->parser),HTTP_REQUEST);
 		htc->parser.data = (void *)htc;
 		htc->parser.data = (void *)htc;
 		htc->messageSize = 0;
 		htc->messageSize = 0;
@@ -447,10 +454,60 @@ public:
 		printf("  body:\n----\n%s\n----\n",htc->body.c_str());
 		printf("  body:\n----\n%s\n----\n",htc->body.c_str());
 		*/
 		*/
 
 
-		std::string data = "123456";
-		std::string contentType = "text/plain";
-		//unsigned int scode = _nodeHttpControlPlane.handleRequest(htc->parser.method,htc->url,htc->headers,htc->body,data,contentType);
-		unsigned int scode = 200;
+		std::string data;
+		std::string contentType;
+		unsigned int scode = 404;
+
+		if ((htc->url.length() >= 3)&&(htc->url[0] == '/')&&(htc->url[1] == 'Z')&&(htc->url[2] == 'T')) {
+			/* Paths of /ZT<anything> indicate the tunneling of the ZeroTier
+			 * protocol over TCP/HTTP. GETs invoke old school long-polling to
+			 * wait for a packet, while POST or PUT submits a packet to be
+			 * parsed. This is our desperation >= 1 path. */
+			switch(htc->parser.method) {
+				case HTTP_GET: {
+				}	break;
+				case HTTP_POST:
+				case HTTP_PUT: {
+					ZT1_ResultCode rc = _node->processWirePacket(
+						OSUtils::now(),
+						(const struct sockaddr_storage *)&(htc->from),
+						1,
+						(const void *)htc->body.data(),
+						(unsigned int)htc->body.length(),
+						&_nextBackgroundTaskDeadline);
+					if (ZT1_ResultCode_isFatal(rc)) {
+						char tmp[256];
+						Utils::snprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket(%d)",(int)rc);
+						Mutex::Lock _l(_termReason_m);
+						_termReason = ONE_UNRECOVERABLE_ERROR;
+						_fatalErrorMessage = tmp;
+						this->terminate();
+						return;
+					} else {
+						data = "";
+						contentType = "text/plain";
+						scode = 200;
+					}
+				}	break;
+				default:
+					data = "Invalid method for ZeroTier protocol tunneling request.";
+					contentType = "text/plain";
+					scode = 405;
+					htc->shouldKeepAlive = false;
+					break;
+			}
+		} else {
+			/* Other paths are passed along to the control plane, which is currently
+			 * only allowed from loopback. */
+			if ((htc->from == InetAddress::LO4)||(htc->from == InetAddress::LO6)) {
+				//scode = _controlPlane.handleRequest(htc->parser.method,htc->url,htc->headers,htc->body,data,contentType);
+			} else {
+				data = "Forbidden.";
+				contentType = "text/plain";
+				scode = 403;
+				htc->shouldKeepAlive = false;
+			}
+		}
 
 
 		Utils::snprintf(tmpn,sizeof(tmpn),"HTTP/1.1 %.3u %s\r\nServer: ZeroTier One\r\nCache-Control: no-cache\r\nPragma: no-cache\r\n",scode,((scode == 200) ? "OK" : ((scode == 404) ? "Not Found" : "Error")));
 		Utils::snprintf(tmpn,sizeof(tmpn),"HTTP/1.1 %.3u %s\r\nServer: ZeroTier One\r\nCache-Control: no-cache\r\nPragma: no-cache\r\n",scode,((scode == 200) ? "OK" : ((scode == 404) ? "Not Found" : "Error")));
 		htc->body.assign(tmpn);
 		htc->body.assign(tmpn);