void kul::http::_1_1PostRequest::send(const std::string& h, const std::string& res, const uint16_t& p){ WSADATA wsaData; if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) KEXCEPT(Exception, "WSAStartup failed"); SOCKET sock = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP); struct hostent *host; host = gethostbyname(h.c_str()); SOCKADDR_IN SockAddr; SockAddr.sin_port = htons(p); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr); if(connect(sock,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0) KEXCEPT(Exception, "Could not connect"); std::string req(toString(h, res)); ::send(sock, req.c_str(), req.size(), 0); char buffer[10000]; int16_t nDataLength; std::string s; while((nDataLength = recv(sock, buffer, 10000, 0)) > 0){ uint16_t i = 0; while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') { s += buffer[i];//do something with buffer[i] i += 1; } memset(&buffer[0], 0, sizeof(buffer)); } handle(s); closesocket(sock); WSACleanup(); }
void maiken::Application::preSetupValidation() throw (maiken::Exception){ { kul::hash::set::String keys; for(YAML::const_iterator it=project().root()[PROPERTY].begin();it!=project().root()[PROPERTY].end(); ++it){ if(keys.count(it->first.Scalar())) KEXCEPTION("Duplicate PROPERTIES: "+it->first.Scalar()+"\n"+project().dir().path()); keys.insert(it->first.Scalar()); } } Validator::PRE_BUILD(*this, project().root()); std::vector<std::string> profiles; for(const auto& profile : project().root()[PROFILE]){ const std::string& p(profile[NAME].Scalar()); if(std::find(profiles.begin(), profiles.end(), p) != profiles.end()) KEXCEPT(Exception, "Duplicate profile name found"); profiles.push_back(p); if(profile[PARENT]){ bool f = 0; for(const auto& p1 : project().root()[PROFILE]){ if(profile[PARENT].Scalar() == p1[NAME].Scalar()) f = 1; if(f) break; } if(!f) KEXCEPTION("parent profile not found: "+profile[PARENT].Scalar()+"\n"+project().dir().path()); } if(profile["os"]) for(const auto& p1 : project().root()[PROFILE]) if(profile[NAME].Scalar() == p1[NAME].Scalar()) continue; else if(p1["os"] && p1["os"].Scalar() == profile["os"].Scalar()) KEXCEPTION("Multiple os tags with same value found, only one per operating system supported\n"+project().dir().path()); Validator::PRE_BUILD(*this, profile); } for(const auto& n : project().root()[PROFILE]) if(n[SELF] && std::find(profiles.begin(), profiles.end(), resolveFromProperties(n[SELF].Scalar())) == profiles.end()) KEXCEPT(Exception, "Tag self references unknown profile: "+n[SELF].Scalar()+"\n"+project().dir().path()); }
static void POST_BUILD(const maiken::Application& a, const YAML::Node& n) throw (maiken::Exception){ std::stringstream ss; for(const auto f : a.files()) ss << f.first << " "; if(n[MAIN] && !a.files().count(n[MAIN].Scalar().substr(n[MAIN].Scalar().rfind(".")+1))) KEXCEPT(maiken::Exception, "main tag invalid type, valid types are\n"+ss.str()+"\n"+a.project().dir().path()); else if(n[LANG] && !a.files().count(n[LANG].Scalar())) KEXCEPT(maiken::Exception, "lang tag invalid type, valid types are\n"+ss.str()+"\n"+a.project().dir().path()); }
static void IF_VALUEDATER(const maiken::Application& a, const YAML::Node& n, const std::string& s, const std::vector<std::string>& lefts){ kul::hash::set::String keys; for(YAML::const_iterator it= n.begin(); it != n.end(); ++it){ if(std::find(lefts.begin(), lefts.end(), it->first.Scalar()) == lefts.end()) KEXCEPT(maiken::Exception, "malformed "+s+" key, \n"+a.project().dir().path()); if(keys.count(it->first.Scalar())) KEXCEPT(maiken::Exception, "Duplicate "+s+"key detected: "+it->first.Scalar()+"\n"+a.project().dir().path()); keys.insert(it->first.Scalar()); } }
static const std::string REPO(const kul::Dir& d, const std::string& r){ if(INSTANCE().valids.count(d.path())) return (*INSTANCE().valids.find(d.path())).second; if(IS_SOLID(r)) INSTANCE().valids.insert(d.path(), r); else GET_SCM(d, r); if(INSTANCE().valids.count(d.path())) return (*INSTANCE().valids.find(d.path())).second; KEXCEPT(Exception, "SCM not discovered for project: "+d.path()); }
static const kul::SCM* GET_SCM(const kul::Dir& d, const std::string& r){ std::vector<std::string> repos; if(IS_SOLID(r)) repos.push_back(r); else for(const std::string& s : Settings::INSTANCE().remoteRepos()) repos.push_back(s + r); for(const auto& repo : repos){ try{ kul::Process g("git"); kul::ProcessCapture gp(g); std::string r1(repo); if(repo.find("http") != std::string::npos && repo.find("@") == std::string::npos) r1 = repo.substr(0, repo.find("//") + 2) + "u:p@" + repo.substr(repo.find("//") + 2); g.arg("ls-remote").arg(r1).start(); if(!gp.errs().size()) { INSTANCE().valids.insert(d.path(), repo); return &kul::scm::Manager::INSTANCE().get("git"); } }catch(const kul::proc::ExitException& e){} try{ kul::Process s("svn"); kul::ProcessCapture sp(s); s.arg("ls").arg(repo).start(); if(!sp.errs().size()) { INSTANCE().valids.insert(d.path(), repo); return &kul::scm::Manager::INSTANCE().get("svn"); } }catch(const kul::proc::ExitException& e){} } std::stringstream ss; for(const auto& s : repos) ss << s << "\n"; KEXCEPT(Exception, "SCM not found or not supported type(git/svn) for repo(s)\n"+ss.str()+"project:"+d.path()); }
bool kul::http::Server::get(PHTTP_REQUEST req){ HTTP_RESPONSE response; initialiseReponse(response, 200, "OK"); addKnownHeader(response, HttpHeaderContentType, "text/html"); HTTP_DATA_CHUNK dataChunk; DWORD result; DWORD bytesSent; std::string s(req->pRawUrl); std::string a; if(s.find("?") != std::string::npos){ a = s.substr(s.find("?") + 1); s = s.substr(0, s.find("?")); } const std::pair<kul::hash::set::String, std::string>& p(handle(s, asAttributes(a))); if(p.second.size()){ dataChunk.DataChunkType = HttpDataChunkFromMemory; dataChunk.FromMemory.pBuffer = (PVOID) p.second.c_str(); dataChunk.FromMemory.BufferLength = p.second.size(); response.EntityChunkCount = 1; response.pEntityChunks = &dataChunk; } result = HttpSendHttpResponse(this->q, req->RequestId, 0, &response, NULL, &bytesSent, NULL, 0, NULL, NULL); if(result != NO_ERROR) KEXCEPT(Exception, "HttpSendHttpResponse failed with: " + std::to_string(result)); return result; }
static int GET(const std::string& s) throw(TypeException){ try{ return std::stoi(s); } catch(const std::invalid_argument& e){ KEXCEPT(TypeException, "stoi failed"); } }
static void PRE_BUILD(const maiken::Application& a, const YAML::Node& n) throw (maiken::Exception){ if(n[MAIN] && n[LANG]) KEXCEPT(maiken::Exception, "cannot have both main and lang tag\n"+a.project().dir().path()); if(n[MAIN]){ const std::string& m(n[MAIN].Scalar()); if(m.find(".") == std::string::npos) KEXCEPT(maiken::Exception, "main tag invalid format, expects <file>.<type>\n"+a.project().dir().path()); } if(n[MODE]){ const auto& s(n[MODE].Scalar()); if(s != NONE && s != STATIC && s != SHARED) KEXCEPT(maiken::Exception, "mode tag invalid value, expects none/static/shared\n"+a.project().dir().path()); } if(n[IF_ARG]) IF_VALUEDATER(a, n[IF_ARG], IF_ARG, INSTANCE().ifArgsLefts); if(n[IF_INC]) IF_VALUEDATER(a, n[IF_INC], IF_ARG, INSTANCE().ifIncSrcLefts); if(n[IF_SRC]) IF_VALUEDATER(a, n[IF_SRC], IF_ARG, INSTANCE().ifIncSrcLefts); if(n[IF_LIB]) IF_VALUEDATER(a, n[IF_SRC], IF_ARG, INSTANCE().ifIncSrcLefts); }
static bool FROM(std::string s){ kul::String::trim(s); const std::vector<std::string>& pos {"yes", "y", "true", "1"}; const std::vector<std::string>& neg {"no", "n", "false", "0"}; std::transform(s.begin(), s.end(), s.begin(), ::tolower); if (std::find(pos.begin(), pos.end(), s) != pos.end()) return true; if (std::find(neg.begin(), neg.end(), s) != neg.end()) return false; KEXCEPT(TypeException, "input not bool-able"); }
const std::string key(std::string comp){ kul::String::replaceAll(comp, ".exe", ""); if(cs.count(comp) > 0)return comp; if(comp.find(" ") != std::string::npos) for(const std::string& s :kul::String::split(comp, ' ')){ if(cs.count(s) > 0) return s; if(std::string(kul::Dir(s).locl()).find(kul::Dir::SEP()) != std::string::npos) if(cs.count(s.substr(s.rfind(kul::Dir::SEP()) + 1)) > 0) return s.substr(s.rfind(kul::Dir::SEP()) + 1); } if(std::string(kul::Dir(comp).locl()).find(kul::Dir::SEP()) != std::string::npos) if(cs.count(comp.substr(comp.rfind(kul::Dir::SEP()) + 1)) > 0) return comp.substr(comp.rfind(kul::Dir::SEP()) + 1); KEXCEPT(CompilerNotFoundException, "Compiler for " + comp + " is not implemented"); }
void kul::http::Server::start() throw(kul::http::Exception){ ULONG RequestBufferLength = sizeof(HTTP_REQUEST) + 2048; PCHAR pRequestBuffer = (PCHAR) wAlloc(RequestBufferLength); if(pRequestBuffer == NULL) KEXCEPT(Exception, "Buffer allocation failed: " + std::to_string(ERROR_NOT_ENOUGH_MEMORY)); PHTTP_REQUEST req = (PHTTP_REQUEST) pRequestBuffer; HTTP_REQUEST_ID requestId; HTTP_SET_NULL_ID(&requestId); DWORD bytesRead; ULONG r = 0; while(1){ RtlZeroMemory(req, RequestBufferLength); r = HttpReceiveHttpRequest(this->q, requestId, 0, req, RequestBufferLength, &bytesRead, NULL); if(r == NO_ERROR){ if(req->Verb == HttpVerbGET){ get(req); }else if(req->Verb == HttpVerbPOST){ post(req); }else if(req->Verb == HttpVerbHEAD){ // head(req); }else KLOG(INF) << "Unrecognised http method type"; }else if(r == ERROR_MORE_DATA){ requestId = req->RequestId; RequestBufferLength = bytesRead; wFreeM(pRequestBuffer); pRequestBuffer = (PCHAR) wAlloc(RequestBufferLength); }else if(r == ERROR_CONNECTION_INVALID && !HTTP_IS_NULL_ID(&requestId)){ HTTP_SET_NULL_ID(&requestId); }else KEXCEPT(Exception, "HttpReceiveHttpRequest failed: " + std::to_string(r)); } }
void kul::https::Requester::send(const std::string& h, const std::string& req, const uint16_t& p, std::stringstream& ss, SSL *ssl){ KUL_DBG_FUNC_ENTER int32_t sck = 0; if (!kul::tcp::Socket<char>::SOCKET(sck, PF_INET, SOCK_STREAM, 0)) KEXCEPT(kul::http::Exception, "Error opening socket"); if(!kul::tcp::Socket<char>::CONNECT(sck, h, p)) KEXCEPT(kul::http::Exception, "Failed to connect to host: " + h); SSL_set_fd(ssl, sck); if (SSL_connect(ssl) == -1) KEXCEPTION("HTTPS REQUEST INIT FAILED"); SSL_write(ssl, req.c_str(), req.size()); char buffer[_KUL_HTTPS_REQUEST_BUFFER_]; do{ int16_t d = SSL_read(ssl, buffer, _KUL_HTTPS_REQUEST_BUFFER_ - 1); if (d == 0) break; if (d < 0){ short se = 0; SSL_get_error(ssl, se); if(se) KLOG(ERR) << "SSL_get_error: " << se; break; } for(uint16_t i = 0; i < d; i++) ss << buffer[i]; }while(1); ::close(sck); }
void kul::http::Server::stop(){ ULONG r = 0; HttpShutdownRequestQueue(q); if(r != NO_ERROR) KEXCEPT(Exception, "HttpShutdownRequestQueue failed: " + std::to_string(r)); if(q) CloseHandle(q); }
bool kul::http::Server::post(PHTTP_REQUEST req){ HTTP_RESPONSE response; DWORD result; DWORD bytesSent; ULONG EntityBufferLength = 512; PUCHAR rstr = (PUCHAR) wAlloc(EntityBufferLength); ULONG bytes = 0; CHAR szContentLength[MAX_ULONG_STR]; HTTP_DATA_CHUNK dataChunk; if (rstr == NULL){ postClean(rstr); KEXCEPT(Exception, "Insufficient resources " + std::to_string(ERROR_NOT_ENOUGH_MEMORY)); } initialiseReponse(response, 200, "OK"); if(req->Flags & HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS){ std::string atts; do{ bytes = 0; result = HttpReceiveRequestEntityBody(this->q, req->RequestId, 0, rstr, EntityBufferLength, &bytes, NULL); switch(result){ case NO_ERROR: for(ULONG i = 0; i < bytes; i++) atts += rstr[i]; break; case ERROR_HANDLE_EOF: { for(ULONG i = 0; i < bytes; i++) atts += rstr[i]; sprintf_s(szContentLength, MAX_ULONG_STR, "%lu", bytes); addKnownHeader(response, HttpHeaderContentLength, szContentLength); result = HttpSendHttpResponse(this->q, req->RequestId, HTTP_SEND_RESPONSE_FLAG_MORE_DATA, &response, NULL, &bytesSent, NULL, 0, NULL, NULL); if(result != NO_ERROR){ postClean(rstr); KEXCEPT(Exception, "HttpSendHttpResponse failed with: " + std::to_string(result)); } const std::pair<kul::hash::set::String, std::string>& p(handle(req->pRawUrl, asAttributes(atts))); dataChunk.DataChunkType = HttpDataChunkFromMemory; dataChunk.FromMemory.pBuffer = (PVOID) p.second.c_str(); dataChunk.FromMemory.BufferLength = p.second.size(); result = HttpSendResponseEntityBody(this->q, req->RequestId, 0, 1, &dataChunk, NULL, NULL, 0, NULL, NULL); if(result != NO_ERROR){ postClean(rstr); KEXCEPT(Exception, "HttpSendResponseEntityBody failed with: " + std::to_string(result)); } break; } default: postClean(rstr); return result; } }while(TRUE); }else{ // This request does not have an entity body. result = HttpSendHttpResponse(this->q, req->RequestId, 0, &response, NULL, &bytesSent, NULL,0, NULL, NULL); if(result != NO_ERROR){ postClean(rstr); KEXCEPT(Exception, "HttpSendHttpResponse failed with: " + std::to_string(result)); } } postClean(rstr); return result; }
const SCM& get(const std::string& s) throw(NotFoundException){ if(SCMs.count(s) > 0) return *(*SCMs.find(s)).second; KEXCEPT(NotFoundException, "Source Control Management for " + s + " is not implemented"); }