int CHttpRequest::PostHTTP(CUrl& iUrl, const CString& RawData, const CString& iE, inetSocket& Sock){ CString Request; if (ProxyURL.StrLength() && Proxy.isValid()) { Request += "POST "; Request += iUrl.GetScheme(); Request+="://"; Request += iUrl.GetHost(); if (iUrl.GetPortValue() != 80) { Request+=":"; Request += iUrl.GetPort(); } Request += iUrl.GetUrlPath(); Request += " HTTP/1.0"; Request+=iE; } else { Request += "POST "; Request += iUrl.GetUrlPath(); Request += " HTTP/1.0"; Request+=iE; Request += "Host: "; Request += iUrl.GetHost(); Request+=iE; } for (int i=0;i<RHeaderParams.entries_count();i++) { Request+=RHeaderParams.get_name(i); Request+=": "; Request+=RHeaderParams.get_value(i); Request += iE; } Request += iE; Request += RawData; if (!Send(Sock, Request)) return 0; ProcessHeader(Sock); ProcessData(Sock); if (RData.StrLength()) { RHeaderResponse.clear(); RStatusValue = 200; RStatus = "200"; return 1; } else return 0; }
CVector<CString> CUrlTree::UrlToVector(const CUrl& Url) const { CVector<CString> Vector; CString MidString; MidString += Url.GetScheme(); MidString += ":/"; #ifdef _UNIX if (Url.GetScheme().Same(g_strProto_FILE)) { MidString += "/"; } #endif Vector += MidString; MidString = Url.GetHost(); if (MidString.GetLength() && Url.GetPortValue() != 80) { MidString += ":"; MidString += Url.GetPort(); } if (MidString.GetLength()) { Vector += MidString; } int HostVectorSize = Vector.GetSize(); CVector<CString> Vector2; CString::StrToVector(Url.GetUrlPath(), '/', &Vector2); Vector += Vector2; if (((int) Vector.GetSize() > HostVectorSize) && (!Vector[HostVectorSize].GetLength())) Vector.RemoveAt(HostVectorSize); return Vector; }
int CHttpRequest::GetHTTP09(CUrl& iUrl, const CString& iE, inetSocket& Sock){ /* attempt a retrieval of HTTP/0.9 */ CString Request; if (RLimit) Request += "GET "; else Request+="HEAD "; Request += iUrl.GetScheme(); Request+="://"; Request += iUrl.GetHost(); if (iUrl.GetPortValue() != 80) { Request+=":"; Request += iUrl.GetPort(); } Request += iUrl.GetUrlPath(); Request+=iE; for (int i=0;i<RHeaderParams.entries_count();i++) { Request+=RHeaderParams.get_name(i); Request+=": "; Request+=RHeaderParams.get_value(i); Request += iE; } Request += iE; #ifdef _U_DEBUG cout << "# HTTP 0.9 Request: =====" << endl; cout << Request; cout << "=====================" << endl; #endif /* issue request */ if (!Send(Sock, Request)) return 0; RHeader.Free(); RData.Free(); RStatus.Free(); RStatusValue = -1; ProcessData(Sock); if (RData.StrLength()) { RHeaderResponse.clear(); RStatusValue = 200; RStatus = "200"; return 1; } else if (RStatusValue != -1) { return 0; } else { RStatusValue = HTTPR_USER + 3; return 0; } }
int CHttpRequest::GetHTTP10(CUrl& iUrl, const CString& iE, inetSocket& Sock){ /* attempt a retrieval of HTTP/1.0 */ CString Request; if (ProxyURL.StrLength() && Proxy.isValid()) { if (RLimit) Request += "GET "; else Request+="HEAD "; Request += iUrl.GetScheme(); Request+="://"; Request += iUrl.GetHost(); if (iUrl.GetPortValue() != 80) { Request+=":"; Request += iUrl.GetPort(); } Request += iUrl.GetUrlPath(); Request += " HTTP/1.0"; Request+=iE; } else { if (RLimit) Request += "GET "; else Request+="HEAD "; Request += iUrl.GetUrlPath(); Request += " HTTP/1.0"; Request+=iE; Request += "Host: "; Request += iUrl.GetHost(); Request+=iE; } for (int i=0;i<RHeaderParams.entries_count();i++) { Request+=RHeaderParams.get_name(i); Request+=": "; Request+=RHeaderParams.get_value(i); Request += iE; } Request += iE; #ifdef _U_DEBUG cout << "# HTTP Request: =====" << endl; cout << Request; cout << "=====================" << endl; #endif /* issue request */ CString RLoc; if (!Send(Sock, Request)) return 0; ProcessHeader(Sock); ProcessData(Sock); switch(RStatusValue) { case 200: return 1; case 301: case 302: case 303: case 307: if (!FollowRedirections) return RStatusValue; RLoc = RHeaderResponse.get_value("Location"); if (RLoc.StrLength()) { /* HTTP 1.1 - Temporary Redirect is 302 and 307 RedirectVector is relevant for final URL address that could be retrieved */ if (!RedirectVector.Contains(RLoc)) { RedirectVector+=RLoc; CUrl NewURL(RLoc); if (!Proxy.isValid()) { inetSocket Sock2(NewURL.GetPortValue(), NewURL.GetHost()); return GetHTTP10(NewURL, iE, Sock2); } else { Sock.Reopen(); return GetHTTP10(NewURL, iE, Sock); } } } return RStatusValue; case 305: /* use proxy */ RLoc = RHeaderResponse.get_value("Location"); if (RLoc.StrLength()) { CUrl ProxyURL(RLoc); if (ProxyURL.isValid()) { inetSocket ProxySock(ProxyURL.GetPortValue(), ProxyURL.GetHost()); if (wsLastError.StrLength()) return RStatusValue; return GetHTTP10(iUrl, iE, ProxySock); } } return RStatusValue; default: return RStatusValue; } }
int RunConverter( int argc, _TCHAR* * argv ) { #ifdef _DEBUG // sleep a bit so we can have time to attach a debugger Tell(_T("Sleeping for %d seconds in debug mode."), startupTimeout / 1000); Sleep(startupTimeout); #endif int ret = 0; wstring name; wstring title; HANDLE conversionHandle = NULL; po::options_description desc("Converts an MPEG-2 Program Stream to a DVR-MS, WMV, or WTV file."); po::positional_options_description pos; string input; string output; LONGLONG length; bool disableFileLogging; bool disableConsoleLogging; bool disableAllLogging; string interruptName; string interruptDirectory; string outputDirectory; string contentTitle; __int64 contentDuration = -1i64; desc.add_options() ("help,?", "Display help message.") ("input,i", po::value<string>(&input), "an MPEG2 input path. Can be a url.") ("output,o", po::value<string>(&output), "output path.<type>. Where <type> can be one of \"dvr-ms\", \"wmv\", or \"wtv\"") ("length,l", po::value<LONGLONG>(&length)->default_value(-1), "the length of the input content in bytes. Only required for a network path such as http." ) ("interrupt-name", po::value<string>(&interruptName), "the file name (without path or extension) of a file that will be created when conversion is to be interrupted.") ("interrupt-directory", po::value<string>(&interruptDirectory), "the path for this app to look for an interrupt file. An interrupt file is the interrupt_file name with a .interrupt extension. The file itself can be empty.") ("disable-file-logging", po::value<bool>(&disableFileLogging)->zero_tokens()->default_value(false), "indicates that logging to a file will be disabled.") ("disable-console-logging", po::value<bool>(&disableConsoleLogging)->zero_tokens()->default_value(false), "indicates that logging to the console will be disabled.") ("disable-all-logging", po::value<bool>(&disableAllLogging)->zero_tokens()->default_value(false), "indicates that all logging will be disabled.") ("output-directory,d", po::value<string>(&outputDirectory), "the directory for this app to place conversion output. Only valid if output_path is omitted.") ("content-title,t", po::value<string>(&contentTitle), "the Title that will be assigned to the output path.<type>.") ("version,v", po::value<string>()->zero_tokens(), "prints the version of this app.") //("content-duration,d", po::value<__int64>(&contentDuration)->default_value(-1i64), "the duration of the input content in seconds." ) ; pos.add("input", 1); pos.add("output", 1); pos.add("length", 1); vector<string> args; for (int i = 1; i < argc; i++) args.push_back(WStringToString(argv[i])); po::variables_map variables; try { po::basic_parsed_options<char> oo = po::command_line_parser(args). options(desc).positional(pos).run(); po::store(oo, variables); po::notify(variables); } catch (std::exception e) { Tell(_T("Invalid command line. Use --help to see options.")); return -1; } if (!variables.count("input")) { bool display = false; wstring message; if (variables.count("version")) { message = _T("Version: "); message += MPEG2DVRMS_VERSION; display = true; } if (variables.count("help")) { message = _T("eh... help message not available yet. Hope you have the source!"); display = true; } if (!display) message = _T("No input file was specified."); ret = 100; Tell(message); } else { try { ////////////////////////////////////////////////////////////////////////// // command-line option handling LONGLONG contentLength = -1; if (variables.count("length")) contentLength = length; if (variables.count("interrupt-name")) name = StringToWString(interruptName); else { name = NewGuid(); Tell(_T("Generated interrupt name is %s"), name.c_str()); } if (variables.count("interrupt-directory")) _conversionFileStoragePath = StringToWString(interruptDirectory); if (variables.count("content-title")) title = StringToWString(contentTitle); else title = _T(""); #pragma region input output file handling wstring defaultExtension; if (IsVista()) defaultExtension = _T(".dvr-ms"); else defaultExtension = _T(".wtv"); ATL_URL_SCHEME urlScheme; CUrl inputUrl; if (!inputUrl.CrackUrl(StringToWString(input).c_str())) urlScheme = ATL_URL_SCHEME_FILE; else urlScheme = inputUrl.GetScheme(); if (urlScheme == -1) urlScheme = ATL_URL_SCHEME_FILE; wstring inputPath = StringToWString(input); CPath outputPath; if (urlScheme == ATL_URL_SCHEME_FILE) { CPath input = inputPath.c_str(); if (input.IsFileSpec()) { TCHAR szCurrentDirectory[MAX_PATH]; if (!GetCurrentDirectory(MAX_PATH, szCurrentDirectory)) throw CarverLab::Exception(GetLastError()); wstring currentDirectory = (LPCTSTR)szCurrentDirectory; inputPath = currentDirectory + _T("\\") + inputPath.c_str(); input = inputPath.c_str(); } if (!input.FileExists()) throw CarverLab::Exception(_T("MPEG2 input path does not exist.")); if (!variables.count("output")) outputPath = inputPath.c_str(); else outputPath = StringToWString(output).c_str(); } else if (urlScheme == ATL_URL_SCHEME_HTTP || urlScheme == ATL_URL_SCHEME_HTTPS) { if (!variables.count("output")) { wstring thefullpath; CString envString; envString.GetEnvironmentVariable(_T("PUBLIC")); thefullpath = envString; thefullpath += _T("\\Videos\\mpeg2dvrms-output"); thefullpath += defaultExtension; outputPath = thefullpath.c_str(); } else outputPath = StringToWString(output).c_str(); } else throw CarverLab::Exception(_T("Only http or https URL schemes are supported.")); bool isUrl = urlScheme != ATL_URL_SCHEME_FILE; CPath inPath = inputPath.c_str(); if (outputPath.GetExtension().MakeLower() == inPath.GetExtension().MakeLower()) outputPath.RenameExtension(defaultExtension.c_str()); if (outputPath.GetExtension().MakeLower() == _T(".dvrms")) { outputPath.RemoveExtension(); outputPath.AddExtension(_T(".dvr-ms")); } #pragma endregion input output file handling ////////////////////////////////////////////////////////////////////////// conversionHandle = CreateConversion(false, CComBSTR(name.c_str())); if (!conversionHandle) throw CarverLab::Exception(); SetConsoleTitle(outputPath); Tell(_T("Press ENTER to interrupt and exit.")); _done = false; HANDLE stdinput = GetStdHandle(STD_INPUT_HANDLE); std::auto_ptr<InternalThreadData> threadData(new InternalThreadData); threadData->activityCallback = ActivityCallback; threadData->contentLength = contentLength; threadData->conversionHandle = conversionHandle; threadData->inputPath = inPath; threadData->isUrl = isUrl; threadData->outputPath = outputPath; threadData->threadData = NULL; threadData->userData = NULL; threadData->contentTitle = StringToWString(contentTitle); threadData->contentDuration = contentDuration; _lastConvertedFilePath = outputPath; HANDLE thread = CreateThread(NULL, 0, BeginConversion, threadData.get(), 0, NULL); if (thread == NULL) throw CarverLab::Exception(); bool shuttingDown = false; bool interruptSuccessful = false; // will be true if the conversion is inactive after InterruptConversion is called while (!_done) { if (!shuttingDown && ((_kbhit() && _getch() == 13) || InterruptNow(name.c_str()))) { shuttingDown = true; interruptSuccessful = InterruptConversion(conversionHandle, 30000); // will wait 30 seconds for the conversion to die } Sleep(10); } if (!interruptSuccessful) { // TODO: will need to kill this puppy in an unnice way... awwww Tell(_T("InterruptConversion was unsusccessful.")); } // TODO: INFINITE? um... nope. this will need an intervention WaitForSingleObject(thread, INFINITE); CloseHandle(thread); } catch (CarverLab::Exception exception) { Tell(_T("*** Error: %s"), exception.GetErrorString()); Tell(_T("Exiting...")); ret = exception.GetHRESULT(); } catch (...) { DWORD errorCode = GetLastError(); wstring error = Exception::GetLastErrorString(errorCode); Tell(_T("*** Unhandled Exception: %s"), error.c_str()); Tell(_T("Exiting...")); ret = errorCode; } if (conversionHandle != NULL) CloseConversion(conversionHandle); } #ifdef _DEBUG // sleep a bit so we can see any errors Tell(_T("Sleeping for %d seconds in debug mode."), sleepTimeout / 1000); Sleep(sleepTimeout); #endif return ret; }