#include #include #include #include #include #pragma comment(lib, "ws2_32.lib") int main(int argc, const char** argv) { const char* const querry = getenv("QUERY_STRING"); std::string src((querry && *querry) ? _strnicmp(querry, "url=", 4) ? querry : querry + 4 : ""); if (src[0]) for (auto i = src.rfind('%'); i != std::string::npos; i = src.rfind('%', i - 1)) src.replace(i, 3, 1, static_cast(std::strtol(src.substr(i + 1, 2).c_str(), nullptr, 16))); std::cout << "Content-Type: text/html; charset=UTF-8" << std::endl << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "Expand URL" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "
" << std::endl; std::cout << "Enter the shortened URL:" << std::endl; if (src[0]) std::cout << "" << std::endl; else std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "
" << std::endl; if (src[0]) { std::cout << "
" << std::endl; std::cout << "
" << std::endl; try { WSADATA wsaData; if (WSAStartup(MAKEWORD(2,0), &wsaData)) throw std::string("WSAStartup failed\n"); try { std::string src(_strnicmp(querry, "url=", 4) ? querry : querry + 4); for (auto i = src.rfind('%'); i != std::string::npos; i = src.rfind('%', i - 1)) src.replace(i, 3, 1, static_cast(std::strtol(src.substr(i + 1, 2).c_str(), nullptr, 16))); const boost::basic_regex exp("^(\?:([^:/\?#]+)://)\?(\\w+[^/\?#:]*)(\?::(\\d+))\?(/\?([^#]*))\?"); std::vector values; values.reserve(4); std::string res; for (int i = 0; i < 16; ++i) { std::cout << "
" << std::endl; std::cout << "
#" << i << "
"; std::cout << "" << std::endl; if (!boost::regex_split(std::back_inserter(values), src, exp)) throw std::string("Failed to perse url: ") + src; if (_stricmp(values[0].c_str(), "http")) throw std::string("URL Scheme "") + values[0] + "" is not supported."; const hostent* const hoste = gethostbyname(values[1].c_str()); if (!hoste) throw WSAGetLastError() == WSAHOST_NOT_FOUND ? values[1] + " not found" : std::string("gethostbyname failed"); const unsigned int* const* addrptr = reinterpret_cast(hoste->h_addr_list); const unsigned short port = values[2][0] ? static_cast(std::atoi(values[2].c_str())) : 80; sockaddr_in server = {AF_INET, htons(port)}; const SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) throw std::string("socket failed\n"); std::cout << "
" << std::endl; std::cout << "
  
" << std::endl; try { std::cout << "
" << std::endl; for (; *addrptr; ++addrptr) { server.sin_addr.S_un.S_addr = **addrptr; if (!connect(sock, reinterpret_cast(&server), sizeof(server))) break; } if (!*addrptr) throw std::string("connect failed\n"); std::cout << "
  " << values[1]; if (values[2][0]) std::cout << ":" << values[2]; std::cout << " " << static_cast(server.sin_addr.S_un.S_un_b.s_b1) << "." << static_cast(server.sin_addr.S_un.S_un_b.s_b2) << "." << static_cast(server.sin_addr.S_un.S_un_b.s_b3) << "." << static_cast(server.sin_addr.S_un.S_un_b.s_b4) << ":" << port << "
" << std::endl; std::cout << "
" << std::endl; std::cout << "+ HEAD " << values[3] << " HTTP/1.1
" << std::endl; std::cout << "  Host: " << values[1] << "
" << std::endl; std::cout << "  Connection: close
" << std::endl; std::cout << "
" << std::endl; const std::string req(std::string("HEAD ") + values[3] + " HTTP/1.1\r\nHost: " + values[1] + "\r\nConnection: close\r\n\r\n"); int n = send(sock, req.c_str(), req.length(), 0); if (n < 0) throw std::string("send to ") + values[1] + " failed\n"; while (n > 0) { char buf[1024] = {}; n = recv(sock, buf, sizeof(buf) - 1, 0); if (n < 0) throw std::string("recv from ") + values[1] + " failed\n"; res += buf; for (auto i = res.find('\r'); i != std::string::npos; i = res.find('\r', i)) res.erase(i, 1); const auto retpos = res.find("\n\n"); if (retpos == std::string::npos) continue; res.erase(retpos); break; } } catch(const std::string) { closesocket(sock); std::cout << "
" << std::endl; std::cout << "
" << std::endl; std::cout << "
" << std::endl; throw; } closesocket(sock); const auto locpos = res.find("\nLocation: "); std::cout << "
" << std::endl << "+ "; for (size_t e = res.find('\n'), s = 0, f = 1; ; s = e + 1, e = res.find('\n', s)) { if (e != std::string::npos) res[e] = '\0'; std::cout << res.c_str() + s; if (e == std::string::npos) break; if (f) { std::cout << ""; f = 0; } std::cout << "
" << std::endl << "  "; } std::cout << "
" << std::endl; std::cout << "
" << std::endl; std::cout << "
" << std::endl; std::cout << "
" << std::endl; std::cout << "
" << std::endl; std::cout << "" << std::endl; if (locpos == std::string::npos) break; src = std::string(res.c_str() + locpos + 11); if (i == 15) std::cout << "
Error: Redirection Reached the Limit.
" << std::endl; values.clear(); res.clear(); } } catch(const std::string) { std::cout << "" << std::endl; WSACleanup(); throw; } WSACleanup(); } catch(const std::string e) { std::cout << "
Error: " << e << "
" << std::endl; } std::cout << "" << std::endl; } std::cout << "
" << std::endl; std::cout << "expand_url.cpp" << std::endl; std::cout << "2011 Ryosuke839" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; return 0; }