diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-07-31 10:05:00 -0400 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-07-31 10:05:00 -0400 |
commit | 9df88a3933ae75ff2ec9bfa951a71fcc0164df74 (patch) | |
tree | 8f7584a67689685ca4c738aae1c0f8b330130683 /node | |
parent | 3daea24d504af214bfac1bae41727e93ed8a6774 (diff) | |
download | infinitytier-9df88a3933ae75ff2ec9bfa951a71fcc0164df74.tar.gz infinitytier-9df88a3933ae75ff2ec9bfa951a71fcc0164df74.zip |
Change mind again... dump Http. Launcher will do this and will use libcurl. Also fix some format string errors.
Diffstat (limited to 'node')
-rw-r--r-- | node/Address.hpp | 2 | ||||
-rw-r--r-- | node/Http.cpp | 323 | ||||
-rw-r--r-- | node/Http.hpp | 129 | ||||
-rw-r--r-- | node/Network.hpp | 12 |
4 files changed, 7 insertions, 459 deletions
diff --git a/node/Address.hpp b/node/Address.hpp index 8573a268..fce4f20c 100644 --- a/node/Address.hpp +++ b/node/Address.hpp @@ -198,7 +198,7 @@ public: inline std::string toString() const { char buf[16]; - sprintf(buf,"%.10llx",_a); + sprintf(buf,"%.10llx",(unsigned long long)_a); return std::string(buf); }; diff --git a/node/Http.cpp b/node/Http.cpp deleted file mode 100644 index 86ae2d25..00000000 --- a/node/Http.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - * ZeroTier One - Global Peer to Peer Ethernet - * Copyright (C) 2012-2013 ZeroTier Networks LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * -- - * - * ZeroTier may be used and distributed under the terms of the GPLv3, which - * are available at: http://www.gnu.org/licenses/gpl-3.0.html - * - * If you would like to embed ZeroTier into a commercial application or - * redistribute it in a modified binary form, please contact ZeroTier Networks - * LLC. Start here: http://www.zerotier.com/ - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <vector> -#include <set> -#include <list> - -#ifndef _WIN32 -#include <unistd.h> -#endif - -#include "Http.hpp" -#include "Utils.hpp" -#include "InetAddress.hpp" - -static http_parser_settings _http_parser_settings; - -namespace ZeroTier { - -static bool _sendAll(int fd,const void *buf,unsigned int len) -{ - for(;;) { - int n = (int)::send(fd,buf,len,0); - if ((n < 0)&&(errno == EINTR)) - continue; - return (n == (int)len); - } -} - -const std::map<std::string,std::string> Http::EMPTY_HEADERS; - -Http::Request::Request( - Http::Method m, - const std::string &url, - const std::map<std::string,std::string> &rh, - const std::string &rb, - bool (*handler)(Request *,void *,const std::string &,int,const std::map<std::string,std::string> &,const std::string &), - void *arg) : - _url(url), - _requestHeaders(rh), - _handler(handler), - _arg(arg), - _method(m), - _fd(0) -{ - _http_parser_settings.on_message_begin = &Http::Request::_http_on_message_begin; - _http_parser_settings.on_url = &Http::Request::_http_on_url; - _http_parser_settings.on_status_complete = &Http::Request::_http_on_status_complete; - _http_parser_settings.on_header_field = &Http::Request::_http_on_header_field; - _http_parser_settings.on_header_value = &Http::Request::_http_on_header_value; - _http_parser_settings.on_headers_complete = &Http::Request::_http_on_headers_complete; - _http_parser_settings.on_body = &Http::Request::_http_on_body; - _http_parser_settings.on_message_complete = &Http::Request::_http_on_message_complete; - - start(); -} - -Http::Request::~Request() -{ - if (_fd > 0) - ::close(_fd); - join(); -} - -void Http::Request::main() - throw() -{ - char buf[131072]; - - try { - http_parser_init(&_parser,HTTP_RESPONSE); - _parser.data = this; - - http_parser_url urlParsed; - if (http_parser_parse_url(_url.c_str(),_url.length(),0,&urlParsed)) { - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"URL parse error"); - return; - } - if (!(urlParsed.field_set & (1 << UF_SCHEMA))) { - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"URL specifies no schema"); - return; - } - - std::string schema(_url.substr(urlParsed.field_data[UF_SCHEMA].off,urlParsed.field_data[UF_SCHEMA].len)); - - if (schema == "file") { - const std::string filePath(_url.substr(urlParsed.field_data[UF_PATH].off,urlParsed.field_data[UF_PATH].len)); - - uint64_t lm = Utils::getLastModified(filePath.c_str()); - if (lm) { - const std::map<std::string,std::string>::const_iterator ifModSince(_requestHeaders.find("If-Modified-Since")); - if ((ifModSince != _requestHeaders.end())&&(ifModSince->second.length())) { - uint64_t t64 = Utils::fromRfc1123(ifModSince->second); - if ((t64)&&(lm > t64)) { - suicidalThread = !_handler(this,_arg,_url,304,_responseHeaders,""); - return; - } - } - - if (Utils::readFile(filePath.c_str(),_responseBody)) { - _responseHeaders["Last-Modified"] = Utils::toRfc1123(lm); - suicidalThread = !_handler(this,_arg,_url,200,_responseHeaders,_responseBody); - return; - } - } - - suicidalThread = !_handler(this,_arg,_url,404,_responseHeaders,"file not found or not readable"); - return; - } else if (schema == "http") { - if (!(urlParsed.field_set & (1 << UF_HOST))) { - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"URL contains no host"); - return; - } - std::string host(_url.substr(urlParsed.field_data[UF_HOST].off,urlParsed.field_data[UF_HOST].len)); - - std::list<InetAddress> v4,v6; - { - struct addrinfo *res = (struct addrinfo *)0; - if (!getaddrinfo(host.c_str(),(const char *)0,(const struct addrinfo *)0,&res)) { - struct addrinfo *p = res; - do { - if (p->ai_family == AF_INET) - v4.push_back(InetAddress(p->ai_addr)); - else if (p->ai_family == AF_INET6) - v6.push_back(InetAddress(p->ai_addr)); - } while ((p = p->ai_next)); - freeaddrinfo(res); - } - } - - std::list<InetAddress> *addrList; - if (v4.empty()&&v6.empty()) { - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"could not find address for host in URL"); - return; - } else if (v4.empty()) { - addrList = &v6; - } else { - addrList = &v4; - } - InetAddress *addr; - { - addrList->sort(); - addrList->unique(); - unsigned int i = 0,k = 0; - k = rand() % addrList->size(); - std::list<InetAddress>::iterator a(addrList->begin()); - while (i++ != k) ++a; - addr = &(*a); - } - - int remotePort = ((urlParsed.field_set & (1 << UF_PORT))&&(urlParsed.port)) ? (int)urlParsed.port : (int)80; - if ((remotePort <= 0)||(remotePort > 0xffff)) { - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"URL port out of range"); - return; - } - addr->setPort(remotePort); - - _fd = socket(addr->isV6() ? AF_INET6 : AF_INET,SOCK_STREAM,0); - if (_fd <= 0) { - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"could not open socket"); - return; - } - - for(;;) { - if (connect(_fd,addr->saddr(),addr->saddrLen())) { - if (errno == EINTR) - continue; - ::close(_fd); _fd = 0; - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"connection failed to remote host"); - return; - } else break; - } - - const char *mstr = "GET"; - switch(_method) { - case HTTP_METHOD_HEAD: mstr = "HEAD"; break; - default: break; - } - int mlen = (int)snprintf(buf,sizeof(buf),"%s %s HTTP/1.1\r\nAccept-Encoding: \r\nHost: %s\r\n",mstr,_url.substr(urlParsed.field_data[UF_PATH].off,urlParsed.field_data[UF_PATH].len).c_str(),host.c_str()); - if (mlen >= (int)sizeof(buf)) { - ::close(_fd); _fd = 0; - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"URL too long"); - return; - } - if (!_sendAll(_fd,buf,mlen)) { - ::close(_fd); _fd = 0; - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"write error"); - return; - } - - for(std::map<std::string,std::string>::const_iterator rh(_requestHeaders.begin());rh!=_requestHeaders.end();++rh) { - mlen = (int)snprintf(buf,sizeof(buf),"%s: %s\r\n",rh->first.c_str(),rh->second.c_str()); - if (mlen >= (int)sizeof(buf)) { - ::close(_fd); _fd = 0; - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"header too long"); - return; - } - if (!_sendAll(_fd,buf,mlen)) { - ::close(_fd); _fd = 0; - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"write error"); - return; - } - } - - if (!_sendAll(_fd,"\r\n",2)) { - ::close(_fd); _fd = 0; - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"write error"); - return; - } - - _responseStatusCode = 0; - _messageComplete = false; - for(;;) { - mlen = (int)::recv(_fd,buf,sizeof(buf),0); - if (mlen < 0) { - if (errno != EINTR) - break; - else continue; - } - if (((int)http_parser_execute(&_parser,&_http_parser_settings,buf,mlen) != mlen)||(_parser.upgrade)) { - ::close(_fd); _fd = 0; - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"invalid HTTP response from server"); - return; - } - if (_messageComplete) { - ::close(_fd); _fd = 0; - suicidalThread = !_handler(this,_arg,_url,_responseStatusCode,_responseHeaders,_responseBody); - return; - } - } - - ::close(_fd); _fd = 0; - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"empty HTTP response from server"); - return; - } else { - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"only 'file' and 'http' methods are supported"); - return; - } - } catch ( ... ) { - suicidalThread = !_handler(this,_arg,_url,0,_responseHeaders,"unexpected exception retrieving URL"); - return; - } -} - -int Http::Request::_http_on_message_begin(http_parser *parser) -{ - return 0; -} -int Http::Request::_http_on_url(http_parser *parser,const char *data,size_t length) -{ - return 0; -} -int Http::Request::_http_on_status_complete(http_parser *parser) -{ - Http::Request *r = (Http::Request *)parser->data; - r->_responseStatusCode = parser->status_code; - return 0; -} -int Http::Request::_http_on_header_field(http_parser *parser,const char *data,size_t length) -{ - Http::Request *r = (Http::Request *)parser->data; - if ((r->_currentHeaderField.length())&&(r->_responseHeaders.find(r->_currentHeaderField) != r->_responseHeaders.end())) - r->_currentHeaderField.assign(""); - r->_currentHeaderField.append(data,length); - return 0; -} -int Http::Request::_http_on_header_value(http_parser *parser,const char *data,size_t length) -{ - Http::Request *r = (Http::Request *)parser->data; - if (r->_currentHeaderField.length()) - r->_responseHeaders[r->_currentHeaderField].append(data,length); - return 0; -} -int Http::Request::_http_on_headers_complete(http_parser *parser) -{ - Http::Request *r = (Http::Request *)parser->data; - return ((r->_method == Http::HTTP_METHOD_HEAD) ? 1 : 0); -} -int Http::Request::_http_on_body(http_parser *parser,const char *data,size_t length) -{ - Http::Request *r = (Http::Request *)parser->data; - r->_responseBody.append(data,length); - return 0; -} -int Http::Request::_http_on_message_complete(http_parser *parser) -{ - Http::Request *r = (Http::Request *)parser->data; - r->_messageComplete = true; - return 0; -} - -} // namespace ZeroTier diff --git a/node/Http.hpp b/node/Http.hpp deleted file mode 100644 index a099b15d..00000000 --- a/node/Http.hpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * ZeroTier One - Global Peer to Peer Ethernet - * Copyright (C) 2012-2013 ZeroTier Networks LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * -- - * - * ZeroTier may be used and distributed under the terms of the GPLv3, which - * are available at: http://www.gnu.org/licenses/gpl-3.0.html - * - * If you would like to embed ZeroTier into a commercial application or - * redistribute it in a modified binary form, please contact ZeroTier Networks - * LLC. Start here: http://www.zerotier.com/ - */ - -#ifndef _ZT_HTTP_HPP -#define _ZT_HTTP_HPP - -#include <map> -#include <string> -#include <stdexcept> -#include "Thread.hpp" - -#include "../ext/http-parser/http_parser.h" - -namespace ZeroTier { - -class Http -{ -public: - /** - * HTTP request methods - */ - enum Method - { - HTTP_METHOD_GET, - HTTP_METHOD_HEAD - }; - - /** - * An empty headers map for convenience - */ - static const std::map<std::string,std::string> EMPTY_HEADERS; - - /** - * HTTP request - */ - class Request : protected Thread - { - public: - /** - * Create and issue an HTTP request - * - * The supplied handler is called when the request is - * complete or if an error occurs. A code of zero indicates - * that the server could not be reached, and a description - * of the error will be in 'body'. If the handler returns - * false the Request object deletes itself. Otherwise the - * object must be deleted by other code. - * - * @param m Request method - * @param url Destination URL - * @param rh Request headers - * @param rb Request body or empty string for none (currently unused) - * @param handler Request handler function - * @param arg First argument to request handler - */ - Request( - Http::Method m, - const std::string &url, - const std::map<std::string,std::string> &rh, - const std::string &rb, - bool (*handler)(Request *,void *,const std::string &,int,const std::map<std::string,std::string> &,const std::string &), - void *arg); - - /** - * Destruction cancels any in-progress request - */ - virtual ~Request(); - - protected: - virtual void main() - throw(); - - private: - // HTTP parser handlers - static int _http_on_message_begin(http_parser *parser); - static int _http_on_url(http_parser *parser,const char *data,size_t length); - static int _http_on_status_complete(http_parser *parser); - static int _http_on_header_field(http_parser *parser,const char *data,size_t length); - static int _http_on_header_value(http_parser *parser,const char *data,size_t length); - static int _http_on_headers_complete(http_parser *parser); - static int _http_on_body(http_parser *parser,const char *data,size_t length); - static int _http_on_message_complete(http_parser *parser); - - http_parser _parser; - std::string _url; - - std::map<std::string,std::string> _requestHeaders; - std::map<std::string,std::string> _responseHeaders; - - std::string _currentHeaderField; - std::string _responseBody; - - bool (*_handler)(Request *,void *,const std::string &,int,const std::map<std::string,std::string> &,const std::string &); - void *_arg; - - Http::Method _method; - int _responseStatusCode; - bool _messageComplete; - volatile int _fd; - }; -}; - -} // namespace ZeroTier - -#endif diff --git a/node/Network.hpp b/node/Network.hpp index 62c0e978..637c6664 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -107,14 +107,14 @@ public: inline void setNetworkId(uint64_t id) { char buf[32]; - sprintf(buf,"%llu",id); + sprintf(buf,"%.16llx",(unsigned long long)id); (*this)["nwid"] = buf; } inline uint64_t networkId() const throw(std::invalid_argument) { - return strtoull(get("nwid").c_str(),(char **)0,10); + return strtoull(get("nwid").c_str(),(char **)0,16); } inline void setPeerAddress(Address &a) @@ -137,9 +137,9 @@ public: inline void setTimestamp(uint64_t ts,uint64_t maxDelta) { char foo[32]; - sprintf(foo,"%llu",ts); + sprintf(foo,"%llu",(unsigned long long)ts); (*this)["ts"] = foo; - sprintf(foo,"%llu",maxDelta); + sprintf(foo,"%llu",(unsigned long long)maxDelta); (*this)["~ts"] = foo; } @@ -211,14 +211,14 @@ public: inline void setNetworkId(uint64_t id) { char buf[32]; - sprintf(buf,"%llu",id); + sprintf(buf,"%.16llx",(unsigned long long)id); (*this)["nwid"] = buf; } inline uint64_t networkId() const throw(std::invalid_argument) { - return strtoull(get("nwid").c_str(),(char **)0,10); + return strtoull(get("nwid").c_str(),(char **)0,16); } inline void setPeerAddress(Address &a) |