static HANDLE GetContact(TCHAR *arg, TCHAR **pemail, CMsnProto *proto) { TCHAR* email = NULL; do { TCHAR *tok = _tcschr(arg, '&'); /* next token */ if (tok != NULL) *tok++ = '\0'; if (_tcsnicmp(arg, _T("contact="), 8) == 0) { arg += 8; UrlDecode(arg); email = arg; } arg = tok; } while(arg != NULL); if (email == NULL || email[0] == '\0') { if (pemail) *pemail = NULL; return NULL; } if (pemail) *pemail = email; HANDLE hContact = proto->MSN_HContactFromEmail(UTF8(email), NULL, true, true); return hContact; }
static size_t header_callback(void *ptr, size_t size, size_t rmemb, void *stream) { DownloadInfo *downloadInfo = (DownloadInfo*)stream; char *str = (char*)ptr; //printf("%s\n", str); is_get_header = true; if (!downloadInfo->GetFileName() && strstr(str, "Content-Disposition")) { char *src = strstr(str, "filename="); int length = strlen(src) - 8; char *urlcode_filename = new char[length]; ZeroMemory(urlcode_filename, length); strcpy_s(urlcode_filename, length, (src + 9)); WCHAR* fileName = UrlDecode(urlcode_filename); delete[] urlcode_filename; downloadInfo->SetFileName(fileName); } else if (strstr(str, "Content-Length")) { int length = strlen(str) - 15; char *filesize = new char[length]; strcpy_s(filesize, length, str + 16); FILE_LENGTH size = StringToFileLength(filesize); delete[] filesize; downloadInfo->SetFileSize(size); } return rmemb * size; }
bool PathHasColon( unsigned char *string ) { // No literal colon char *dec = FCalloc( 1, strlen( string ) + 1 ); UrlDecode( dec, (const char *)string ); DEBUG( "Decoded string for path: %s\n", dec ); if( strchr( dec, ':' ) != NULL ) { return TRUE; } return FALSE; }
BOOL PathHasColon( char *string ) { // No literal colon int size = strlen( string ) + 1; char *dec = FCalloc( 1, size ); UrlDecode( dec, (const char *)string ); DEBUG( "[fsysphp] Decoded string for path: %s\n", dec ); if( strchr( dec, ':' ) != NULL ) { return TRUE; } return FALSE; }
char *GHOST_DropTargetX11::FileUrlDecode(char *fileUrl) { if(!strncpy(fileUrl, "file://", 7) == 0) { /* assume one character of encoded URL can be expanded to 4 chars max */ int decodedSize = 4 * strlen(fileUrl) + 1; char *decodedPath = (char *)malloc(decodedSize); UrlDecode(decodedPath, decodedSize, fileUrl + 7); return decodedPath; } return NULL; }
std::string UrlDecodeString(const std::string & encoded){ const char * sz_encoded = encoded.c_str(); size_t needed_length = encoded.length(); for (const char * pch = sz_encoded; *pch; pch++) { if (*pch == '%') needed_length += 2; } needed_length += 10; char stackalloc[64]; char * buf = needed_length > sizeof(stackalloc)/sizeof(*stackalloc) ? (char *)malloc(needed_length) : stackalloc; UrlDecode(encoded.c_str(), buf); std::string result(buf); if (buf != stackalloc) { free(buf); } return result; }
std::string HttpUtil::GetParaFromUrl(const char* url, const char* key) { std::string s = key; s.push_back('='); const char* result = strcasestr(url, s.c_str()); if (NULL != result) { if (result > url && (result[-1] == '?' || result[-1] == '&')) { const char* valueEnd =strchr(result, '&'); if (NULL == valueEnd) { valueEnd = url + strlen(url); } return UrlDecode(std::string(result + s.size(), valueEnd).c_str()); } } return ""; }
bool SmileyCType::CreateTriggerText(char* text) { UrlDecode(text); int len = (int)strlen(text); if (len == 0) return false; int reslen = Netlib_GetBase64DecodedBufferSize(len)+1; char* res = (char*)_malloca(reslen); NETLIBBASE64 nlb = { text, len, ( PBYTE )res, reslen }; if (!CallService(MS_NETLIB_BASE64DECODE, 0, LPARAM( &nlb ))) return false; res[nlb.cbDecoded] = 0; TCHAR *txt = mir_utf8decodeT(res); if (txt == NULL) return false; m_TriggerText = txt; mir_free(txt); return true; }
void RDFormPost::LoadUrlEncoding() { char *data=new char[post_content_length+1]; int n; QStringList lines; QStringList line; if((n=read(0,data,post_content_length))<0) { post_error=RDFormPost::ErrorMalformedData; return; } data[post_content_length]=0; lines=lines.split("&",data); for(unsigned i=0; i<lines.size(); i++) { line=line.split("=",lines[i]); if(line.size()==2) { post_values[line[0]]=UrlDecode(line[1]); post_filenames[line[0]]=false; } } post_error=RDFormPost::ErrorOk; delete data; }
DWORD CRestApiManager::GetSearchEvent(string param, HTTP_STREAM* sendParam, CEpgDBManager* epgDB) { DWORD ret = NO_ERR; map<string,string> paramMap; while(param.size()>0){ string buff; Separate(param, "&", buff, param); if(buff.size()>0){ string key; string val; Separate(buff, "=", key, val); paramMap.insert(pair<string,string>(key, val)); } } map<string,string>::iterator itr; WORD network = 0xFFFF; itr = paramMap.find("network"); if( itr != paramMap.end() ){ network = (WORD)atoi(itr->second.c_str()); } WORD days = 0; itr = paramMap.find("days"); if( itr != paramMap.end() ){ days = (WORD)atoi(itr->second.c_str()); } wstring andkey; itr = paramMap.find("andkey"); if( itr != paramMap.end() ){ string utf8; UrlDecode(itr->second.c_str(), (DWORD)itr->second.size(), utf8); UTF8toW(utf8, andkey); } wstring notkey; itr = paramMap.find("notkey"); if( itr != paramMap.end() ){ string utf8; UrlDecode(itr->second.c_str(), (DWORD)itr->second.size(), utf8); UTF8toW(utf8, notkey); } vector<DWORD> genru; itr = paramMap.find("genru"); if( itr != paramMap.end() ){ string val = itr->second; string id; while(val.size() > 0 ){ Separate(val, "-", id, val); genru.push_back((DWORD)atoi(id.c_str())); } } DWORD index = 0; itr = paramMap.find("index"); if( itr != paramMap.end() ){ index = (DWORD)atoi(itr->second.c_str()); } DWORD count = 200; itr = paramMap.find("count"); if( itr != paramMap.end() ){ count = (DWORD)atoi(itr->second.c_str()); } WORD basicOnly = 1; itr = paramMap.find("basic"); if( itr != paramMap.end() ){ basicOnly = (WORD)atoi(itr->second.c_str()); } //検索条件 EPGDB_SEARCH_KEY_INFO searchKey; searchKey.andKey = andkey; searchKey.notKey = notkey; for( size_t i=0; i<genru.size(); i++){ EPGDB_CONTENT_DATA item; item.content_nibble_level_1 = (BYTE)(genru[i]>>8); item.content_nibble_level_2 = (BYTE)(genru[i]&0x00FF); searchKey.contentList.push_back(item); } //対象サービス vector<EPGDB_SERVICE_INFO> list; if( epgDB->GetServiceList(&list) == TRUE ){ if( network != 0xFFFF ){ for( size_t i=0; i<list.size(); i++ ){ __int64 key = _Create64Key(list[i].ONID,list[i].TSID, list[i].SID); if( 0x7880 <= list[i].ONID && list[i].ONID<= 0x7FE8 ){ //地デジ if( (network & 0x0001) > 0 ){ searchKey.serviceList.push_back(key); } }else if( list[i].ONID == 0x0004 ){ //BS if( (network & 0x0002) > 0 ){ searchKey.serviceList.push_back(key); } }else if( list[i].ONID == 0x0006 || list[i].ONID == 0x0007 ){ //CS if( (network & 0x0004) > 0 ){ searchKey.serviceList.push_back(key); } }else{ //その他 if( (network & 0x0008) > 0 ){ searchKey.serviceList.push_back(key); } } } } } //対象期間 __int64 chkTime = 0; if( days > 0 ){ SYSTEMTIME now; GetLocalTime(&now); now.wHour = 0; now.wMinute = 0; now.wSecond = 0; now.wMilliseconds = 0; chkTime = ConvertI64Time(now); chkTime += days*(29*60*60*I64_1SEC); } vector<EPGDB_SEARCH_KEY_INFO> keyList; keyList.push_back(searchKey); vector<EPGDB_EVENT_INFO*> resultList; wstring xml = L""; string utf8 = ""; epgDB->SearchEpg(&keyList, &resultList); map<__int64, __int64> addID; map<__int64, __int64>::iterator itrAdd; if ( resultList.size() > 0 ){ xml += L"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><entry>"; DWORD total = 0; DWORD findCount = 0; wstring serviceinfo = L"<items>"; wstring buff; for( size_t i = 0; i<resultList.size(); i++){ if( days > 0 ){ if( chkTime < ConvertI64Time(resultList[i]->start_time)){ continue; } } if( resultList[i]->eventGroupInfo != NULL ){ BOOL find = FALSE; for( size_t j=0; j<resultList[i]->eventGroupInfo->eventDataList.size(); j++ ){ __int64 evid = _Create64Key2(resultList[i]->eventGroupInfo->eventDataList[j].original_network_id, resultList[i]->eventGroupInfo->eventDataList[j].transport_stream_id, resultList[i]->eventGroupInfo->eventDataList[j].service_id, resultList[i]->eventGroupInfo->eventDataList[j].event_id); itrAdd = addID.find(evid); if( itrAdd != addID.end() ){ find = TRUE; } } if( find == TRUE ){ continue; } } __int64 evid = _Create64Key2(resultList[i]->original_network_id, resultList[i]->transport_stream_id, resultList[i]->service_id, resultList[i]->event_id); addID.insert(pair<__int64, __int64>(evid,evid)); if( total < index ){ total++; continue; } if( index + count <= total ){ total++; continue; } total++; findCount++; EPGDB_EVENT_INFO* eventInfo = resultList[i]; serviceinfo += L"<eventinfo>"; Format(buff, L"<ONID>%d</ONID>", eventInfo->original_network_id); serviceinfo += buff; Format(buff, L"<TSID>%d</TSID>", eventInfo->transport_stream_id); serviceinfo += buff; Format(buff, L"<SID>%d</SID>", eventInfo->service_id); serviceinfo += buff; Format(buff, L"<eventID>%d</eventID>", eventInfo->event_id); serviceinfo += buff; if( eventInfo->StartTimeFlag == 1 ){ Format(buff, L"<startDate>%04d/%02d/%02d</startDate>", eventInfo->start_time.wYear, eventInfo->start_time.wMonth, eventInfo->start_time.wDay); serviceinfo += buff; Format(buff, L"<startTime>%02d:%02d:%02d</startTime>", eventInfo->start_time.wHour, eventInfo->start_time.wMinute, eventInfo->start_time.wSecond); serviceinfo += buff; Format(buff, L"<startDayOfWeek>%d</startDayOfWeek>", eventInfo->start_time.wDayOfWeek); serviceinfo += buff; } if( eventInfo->DurationFlag == 1 ){ Format(buff, L"<duration>%d</duration>", eventInfo->durationSec); serviceinfo += buff; } if( eventInfo->shortInfo != NULL ){ wstring chk = eventInfo->shortInfo->event_name; CheckXMLChar(chk); Format(buff, L"<event_name>%s</event_name>", chk.c_str()); serviceinfo += buff; chk = eventInfo->shortInfo->text_char; CheckXMLChar(chk); Format(buff, L"<event_text>%s</event_text>", chk.c_str()); serviceinfo += buff; } if( eventInfo->contentInfo != NULL ){ serviceinfo += L""; for( size_t k=0; k<eventInfo->contentInfo->nibbleList.size(); k++){ wstring nibble = L""; Format(nibble,L"<contentInfo><nibble1>%d</nibble1><nibble2>%d</nibble2></contentInfo>", eventInfo->contentInfo->nibbleList[k].content_nibble_level_1, eventInfo->contentInfo->nibbleList[k].content_nibble_level_2); serviceinfo += nibble; } } if( eventInfo->eventGroupInfo != NULL ){ for( size_t k=0; k<eventInfo->eventGroupInfo->eventDataList.size(); k++){ wstring group = L""; Format(group,L"<groupInfo><ONID>%d</ONID><TSID>%d</TSID><SID>%d</SID><eventID>%d</eventID></groupInfo>", eventInfo->eventGroupInfo->eventDataList[k].original_network_id, eventInfo->eventGroupInfo->eventDataList[k].transport_stream_id, eventInfo->eventGroupInfo->eventDataList[k].service_id, eventInfo->eventGroupInfo->eventDataList[k].event_id ); serviceinfo += group; } } Format(buff, L"<freeCAFlag>%d</freeCAFlag>", eventInfo->freeCAFlag); serviceinfo += buff; if( basicOnly == 0 ){ if( eventInfo->extInfo != NULL ){ wstring chk = eventInfo->extInfo->text_char; CheckXMLChar(chk); Format(buff, L"<event_ext_text>%s</event_ext_text>", chk.c_str()); serviceinfo += buff; } if( eventInfo->componentInfo != NULL ){ Format(buff, L"<videoInfo><stream_content>%d</stream_content><component_type>%d</component_type><component_tag>%d</component_tag><text>%s</text></videoInfo>", eventInfo->componentInfo->stream_content, eventInfo->componentInfo->component_type, eventInfo->componentInfo->component_tag, eventInfo->componentInfo->text_char.c_str() ); serviceinfo += buff; } if( eventInfo->audioInfo != NULL ){ for( size_t k=0; k<eventInfo->audioInfo->componentList.size(); k++ ){ Format(buff, L"<audioInfo><stream_content>%d</stream_content><component_type>%d</component_type><component_tag>%d</component_tag><stream_type>%d</stream_type><simulcast_group_tag>%d</simulcast_group_tag><ES_multi_lingual_flag>%d</ES_multi_lingual_flag><main_component_flag>%d</main_component_flag><quality_indicator>%d</quality_indicator><sampling_rate>%d</sampling_rate><text>%s</text></audioInfo>", eventInfo->audioInfo->componentList[k].stream_content, eventInfo->audioInfo->componentList[k].component_type, eventInfo->audioInfo->componentList[k].component_tag, eventInfo->audioInfo->componentList[k].stream_type, eventInfo->audioInfo->componentList[k].simulcast_group_tag, eventInfo->audioInfo->componentList[k].ES_multi_lingual_flag, eventInfo->audioInfo->componentList[k].main_component_flag, eventInfo->audioInfo->componentList[k].quality_indicator, eventInfo->audioInfo->componentList[k].sampling_rate, eventInfo->audioInfo->componentList[k].text_char.c_str() ); serviceinfo += buff; } } if( eventInfo->eventRelayInfo != NULL ){ for( size_t k=0; k<eventInfo->eventRelayInfo->eventDataList.size(); k++){ wstring group = L""; Format(group,L"<relayInfo><ONID>%d</ONID><TSID>%d</TSID><SID>%d</SID><eventID>%d</eventID></relayInfo>", eventInfo->eventRelayInfo->eventDataList[k].original_network_id, eventInfo->eventRelayInfo->eventDataList[k].transport_stream_id, eventInfo->eventRelayInfo->eventDataList[k].service_id, eventInfo->eventRelayInfo->eventDataList[k].event_id ); serviceinfo += group; } } } serviceinfo += L"</eventinfo>"; } serviceinfo += L"</items>"; Format(buff, L"<total>%d</total><index>%d</index><count>%d</count>", total, index, findCount); xml += buff; xml += serviceinfo; xml += L"</entry>"; }else{ xml += L"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><entry>"; xml += L"<err>EPGデータを読み込み中、または存在しません</err>"; xml += L"</entry>"; } WtoUTF8(xml, utf8); sendParam->dataSize = (DWORD)utf8.size(); sendParam->data = new BYTE[sendParam->dataSize]; memcpy(sendParam->data, utf8.c_str(), sendParam->dataSize); if( sendParam->dataSize > 0 ){ Format(sendParam->httpHeader, "HTTP/1.0 200 OK\r\nContent-Type: text/xml\r\nContent-Length: %d\r\nConnection: close\r\n\r\n", sendParam->dataSize); }else{ sendParam->httpHeader = "HTTP/1.0 400 Bad Request\r\nConnection: close\r\n\r\n"; } return ret; }
int CHttpPublicFileSend::HttpRequest(string method, string uri, nocase::map<string, string>* headerList, SOCKET clientSock, HANDLE stopEvent) { int ret = 200; string buff = ""; string path = ""; string rootA = ""; wstring filePath = L""; wstring wbuff = L""; map<string, wstring>::iterator itrVPath; nocase::map<string, string>::iterator itrHead; nocase::map<string, string> httpResHeader; __int64 fileSize = 0; string contentType = ""; __int64 offset = 0; __int64 endPos = 0; map<__int64, __int64> rangeList; if( this->folderPath.size() == 0 || this->rootUri.size() == 0){ ret = 404; goto Err_End; } if( CompareNoCase(method, "GET") != 0 ){ ret = 404; goto Err_End; } WtoA(this->rootUri, rootA); UrlDecode(uri.c_str(), (DWORD)uri.size(), buff); //仮想パスから検索 for(itrVPath = this->virtualPathList.begin(); itrVPath != this->virtualPathList.end(); itrVPath++){ string key; Format(key, "%s/%s/", rootA.c_str(), itrVPath->first.c_str()); if( buff.find(key) == 0 ){ Separate(buff, key, buff, path); Replace(path, "/", "\\"); UTF8toW(path, wbuff); filePath = itrVPath->second; ChkFolderPath(filePath); filePath += L"\\"; filePath += wbuff; break; } } if(filePath.size() == 0 ){ //通常のルート Separate(buff, rootA, buff, path); Replace(path, "/", "\\"); UTF8toW(path, wbuff); filePath = this->folderPath; ChkFolderPath(filePath); filePath += L"\\"; filePath += wbuff; } if( PathFileExists(filePath.c_str()) == FALSE ){ ret = 404; goto Err_End; } httpSend.GetContentType(filePath, contentType); fileSize = httpSend.GetContentLength(filePath); endPos = fileSize; itrHead = headerList->find("Range"); if( itrHead == headerList->end() ){ //Rangeなし Format(buff, "%I64d", fileSize); httpResHeader.insert(pair<string, string>("Content-Length", buff)); httpResHeader.insert(pair<string, string>("Content-Type", contentType)); httpSend.SendResponseHeader(200, &httpResHeader, clientSock, stopEvent); httpSend.SendFile(filePath, offset, endPos, clientSock, stopEvent); }else{ if( httpSend.ParseRangeHeader(fileSize, itrHead->second, &rangeList) == FALSE ){ //Range指定が何かおかしい Format(buff, "%I64d", fileSize); httpResHeader.insert(pair<string, string>("Content-Length", buff)); httpResHeader.insert(pair<string, string>("Content-Type", contentType)); httpSend.SendResponseHeader(200, &httpResHeader, clientSock, stopEvent); httpSend.SendFile(filePath, offset, endPos, clientSock, stopEvent); }else{ httpResHeader.insert(pair<string, string>("Accept-Ranges", "bytes")); if( rangeList.size() > 1 ){ //複数の場所指定 Format(buff, "multipart/byteranges; boundary=%s", MULTI_PART_BOUNDARY); httpResHeader.insert(pair<string, string>("Content-Type", buff)); httpSend.SendResponseHeader(206, &httpResHeader, clientSock, stopEvent); map<__int64, __int64>::iterator itr; string boundary = ""; for( itr = rangeList.begin(); itr != rangeList.end(); itr++ ){ boundary = "--"; boundary += MULTI_PART_BOUNDARY; boundary += "\r\n"; Format(buff, "Content-Type: %s\r\n", contentType); boundary += buff; Format(buff, "Content-Range: bytes %I64d-%I64d/%I64d\r\n", itr->first, itr->second, fileSize); boundary += buff; boundary += "\r\n"; if( httpSend.SendData((BYTE*)boundary.c_str(), (DWORD)boundary.size(), clientSock, stopEvent) != NO_ERR ){ goto End; } if( httpSend.SendFile(filePath, itr->first, itr->second+1, clientSock, stopEvent) != NO_ERR ){ goto End; } boundary = "\r\n"; httpSend.SendData((BYTE*)boundary.c_str(), (DWORD)boundary.size(), clientSock, stopEvent); } boundary = "--"; boundary += MULTI_PART_BOUNDARY; boundary += "--\r\n"; httpSend.SendData((BYTE*)boundary.c_str(), (DWORD)boundary.size(), clientSock, stopEvent); }else{ //一カ所のみ map<__int64, __int64>::iterator itr; itr = rangeList.begin(); httpResHeader.insert(pair<string, string>("Content-Type", contentType)); Format(buff, "bytes %I64d-%I64d/%I64d", itr->first, itr->second, fileSize); httpResHeader.insert(pair<string, string>("Content-Range", buff)); Format(buff, "%I64d", itr->second-itr->first+1); httpResHeader.insert(pair<string, string>("Content-Length", buff)); httpSend.SendResponseHeader(206, &httpResHeader, clientSock, stopEvent); httpSend.SendFile(filePath, itr->first, itr->second+1, clientSock, stopEvent); } } } return ret; Err_End: httpSend.SendResponseHeader(ret, &httpResHeader, clientSock, stopEvent); End: return ret; }
void *server(void *vargp) { pthread_detach(pthread_self()); SOCKET clientfd = *(int *)vargp; delete vargp; char buf[BUF_SIZE + 1]; int blen = 0; buf[0] = 0; char *s; do { int nl = recv(clientfd, buf + blen, BUF_SIZE, 0); if (nl < 0) { closesocket(clientfd); return NULL; } blen += nl; buf[blen] = 0; } while (!(s = strstr(buf, "\r\n\r\n"))); *s = 0; s += 4; blen -= (s - buf); char *l = strstr(buf, "\r\nContent-Length:"); if (!l) { closesocket(clientfd); return NULL; } l += 17; int len; if (sscanf(l, "%d", &len) != 1 || len <= 0) { closesocket(clientfd); return NULL; } s[len] = 0; while (blen < len) { int nl = recv(clientfd, s + blen, len - blen, 0); if (nl < 0) { closesocket(clientfd); return NULL; } blen += nl; } //puts(s); const char *header = "HTTP/1.0 200 OK\r\nAccess-Control-Allow-Origin: *\r\n\r\n"; send(clientfd, header, strlen(header), 0); std::map<std::string, std::string> args; while (*s) { char *eq = strchr(s, '='); *eq = 0; std::string name = s; s = eq + 1; char *token = strchr(s, '&'); if (token) { *token = 0; args[name] = s; s = token + 1; } else { args[name] = s; break; } } if (args.count(std::string("code"))) { std::string k = args[std::string("code")]; k = UrlDecode(k); strcpy(s, k.c_str()); //ans = (char *)malloc(10000); // code is stored in the string s char tmpstr[100]; k = args[std::string("width")]; k = UrlDecode(k); DrawWidth = strtol(k.c_str(), 0, 10); k = args[std::string("height")]; k = UrlDecode(k); DrawHeight = strtol(k.c_str(), 0, 10); WaitForSingleObject(mutex, INFINITE); ans = ""; errors = ""; bgans = ""; printf("the s is: %s\n", s); vars.clear(); funcs.clear(); yylineno = 1; yyparse(s); printf("the root is: 0x%lx", root); if (root) { root->evaluate(); delete root; root = NULL; } else { ans = "error! cannot run!"; } ans = errors + bgans + ans; len = ans.length(); //printf("%s\n", ans.c_str()); send(clientfd, ans.c_str(), len, 0); //free(ans); ReleaseMutex(mutex); } closesocket(clientfd); return NULL; }
// Assigns a new URL to the object. bool URL::SetURL(const String& _url) { url_dirty = false; url = _url; // Make sure an Empty URL is completely Empty. if (url.Empty()) { protocol.Clear(); login.Clear(); password.Clear(); host.Clear(); port = 0; path.Clear(); file_name.Clear(); extension.Clear(); return true; } // Find the protocol. This consists of the string appearing before the // '://' token (ie, file://, http://). const char* host_begin = strchr(_url.CString(), ':'); if (NULL != host_begin) { protocol.Assign(_url.CString(), host_begin); if (0 != strncmp(host_begin, "://", 3)) { char malformed_terminator[4] = {0, 0, 0, 0}; strncpy(malformed_terminator, host_begin, 3); Log::Message(Log::LT_ERROR, "Malformed protocol identifier found in URL %s; expected %s://, found %s%s.\n", _url.CString(), protocol.CString(), protocol.CString(), malformed_terminator); return false; } host_begin += 3; } else { protocol = DEFAULT_PROTOCOL; host_begin = _url.CString(); } // We only want to look for a host if a protocol was specified. const char* path_begin; if (host_begin != _url.CString()) { // Find the host. This is the string appearing after the protocol or after // the username:password combination, and terminated either with a colon, // if a port is specified, or a forward slash if there is no port. // Check for a login pair const char* at_symbol = strchr( host_begin, '@' ); if ( at_symbol ) { String login_password; login_password.Assign( host_begin, at_symbol ); host_begin = at_symbol + 1; const char* password_ptr = strchr( login_password.CString(), ':' ); if ( password_ptr ) { login.Assign( login_password.CString(), password_ptr ); password.Assign( password_ptr + 1 ); } else { login = login_password; } } // Get the host portion path_begin = strchr(host_begin, '/'); // Search for the colon in the host name, which will indicate a port. const char* port_begin = strchr(host_begin, ':'); if (NULL != port_begin && (NULL == path_begin || port_begin < path_begin)) { if (1 != sscanf(port_begin, ":%d", &port)) { Log::Message(Log::LT_ERROR, "Malformed port number found in URL %s.\n", _url.CString()); return false; } host.Assign(host_begin, port_begin); // Don't continue if there is no path. if (NULL == path_begin) { return true; } // Increment the path string past the trailing slash. ++path_begin; } else { port = -1; if (NULL == path_begin) { host = host_begin; return true; } else { // Assign the host name, then increment the path string past the // trailing slash. host.Assign(host_begin, path_begin); ++path_begin; } } } else { path_begin = _url.CString(); } // Check for parameters String path_segment; const char* parameters = strchr(path_begin, '?'); if ( parameters ) { // Pull the path segment out, so further processing doesn't read the parameters path_segment.Assign(path_begin, parameters); path_begin = path_segment.CString(); // Loop through all parameters, loading them StringList parameter_list; StringUtilities::ExpandString( parameter_list, parameters + 1, '&' ); for ( size_t i = 0; i < parameter_list.size(); i++ ) { // Split into key and value StringList key_value; StringUtilities::ExpandString( key_value, parameter_list[i], '=' ); key_value[0] = UrlDecode(key_value[0]); if ( key_value.size() == 2 ) this->parameters[key_value[0]] = UrlDecode(key_value[1]); else this->parameters[key_value[0]] = ""; } } // Find the path. This is the string appearing after the host, terminated // by the last forward slash. const char* file_name_begin = strrchr(path_begin, '/'); if (NULL == file_name_begin) { // No path! file_name_begin = path_begin; path = ""; } else { // Copy the path including the trailing slash. path.Assign(path_begin, ++file_name_begin); // Normalise the path, stripping any ../'s from it size_t parent_dir_pos = String::npos; while ((parent_dir_pos = path.Find("/..")) != String::npos) { // If we found a /.. we should be able to find the start of the parent // directory, if we can't something wierd has happend, bail size_t parent_dir_start_pos = path.RFind("/", parent_dir_pos); if (parent_dir_start_pos == String::npos) break; // Strip out the parent dir and the /.. path.Erase(parent_dir_start_pos, parent_dir_pos - parent_dir_start_pos + 3); // We've altered the URL, mark it dirty url_dirty = true; } } // Find the file name. This is the string after the trailing slash of the // path, and just before the extension. const char* extension_begin = strrchr(file_name_begin, '.'); if (NULL == extension_begin) { file_name = file_name_begin; extension = ""; } else { file_name.Assign(file_name_begin, extension_begin); extension = extension_begin + 1; } return true; }
int CHttpRecFileSend::HttpRequest(string method, string uri, nocase::map<string, string>* headerList, SOCKET clientSock, HANDLE stopEvent) { int ret = 200; string buff = ""; string path = ""; string rootA = ""; wstring filePath = L""; nocase::map<string, string> httpResHeader; nocase::map<string, string>::iterator itrHead; __int64 fileSize = 0; string contentType = ""; __int64 offset = 0; __int64 endPos = 0; map<__int64, __int64> rangeList; DWORD id = 0; map<DWORD, REC_FILE_INFO>::iterator itrInfo; if( this->rootUri.size() == 0){ ret = 404; goto Err_End; } if( CompareNoCase(method, "GET") != 0 ){ ret = 404; goto Err_End; } WtoA(this->rootUri, rootA); UrlDecode(uri.c_str(), (DWORD)uri.size(), buff); //通常のルート Separate(buff, rootA, buff, path); if(path.size() == 0 || path.compare("list.html") == 0){ //ファイル一覧のHTMLを返す ret = SendRecFileList(headerList, clientSock, stopEvent); goto End; } id = atoi(path.c_str()); itrInfo = this->recInfoList.find(id); if( itrInfo == this->recInfoList.end()){ ret = 404; goto Err_End; } filePath = itrInfo->second.recFilePath; if( PathFileExists(filePath.c_str()) == FALSE ){ ret = 404; goto Err_End; } httpSend.GetContentType(filePath, contentType); fileSize = httpSend.GetContentLength(filePath); endPos = fileSize; itrHead = headerList->find("Range"); if( itrHead == headerList->end() ){ //Rangeなし Format(buff, "%I64d", fileSize); httpResHeader.insert(pair<string, string>("Content-Length", buff)); httpResHeader.insert(pair<string, string>("Content-Type", contentType)); httpSend.SendResponseHeader(200, &httpResHeader, clientSock, stopEvent); httpSend.SendFile(filePath, offset, endPos, clientSock, stopEvent); }else{ if( httpSend.ParseRangeHeader(fileSize, itrHead->second, &rangeList) == FALSE ){ //Range指定が何かおかしい Format(buff, "%I64d", fileSize); httpResHeader.insert(pair<string, string>("Content-Length", buff)); httpResHeader.insert(pair<string, string>("Content-Type", contentType)); httpSend.SendResponseHeader(200, &httpResHeader, clientSock, stopEvent); httpSend.SendFile(filePath, offset, endPos, clientSock, stopEvent); }else{ httpResHeader.insert(pair<string, string>("Accept-Ranges", "bytes")); if( rangeList.size() > 1 ){ //複数の場所指定 Format(buff, "multipart/byteranges; boundary=%s", MULTI_PART_BOUNDARY); httpResHeader.insert(pair<string, string>("Content-Type", buff)); httpSend.SendResponseHeader(206, &httpResHeader, clientSock, stopEvent); map<__int64, __int64>::iterator itr; string boundary = ""; for( itr = rangeList.begin(); itr != rangeList.end(); itr++ ){ boundary = "--"; boundary += MULTI_PART_BOUNDARY; boundary += "\r\n"; Format(buff, "Content-Type: %s\r\n", contentType); boundary += buff; Format(buff, "Content-Range: bytes %I64d-%I64d/%I64d\r\n", itr->first, itr->second, fileSize); boundary += buff; boundary += "\r\n"; if( httpSend.SendData((BYTE*)boundary.c_str(), (DWORD)boundary.size(), clientSock, stopEvent) != NO_ERR ){ goto End; } if( httpSend.SendFile(filePath, itr->first, itr->second+1, clientSock, stopEvent) != NO_ERR ){ goto End; } boundary = "\r\n"; httpSend.SendData((BYTE*)boundary.c_str(), (DWORD)boundary.size(), clientSock, stopEvent); } boundary = "--"; boundary += MULTI_PART_BOUNDARY; boundary += "--\r\n"; httpSend.SendData((BYTE*)boundary.c_str(), (DWORD)boundary.size(), clientSock, stopEvent); }else{ //一カ所のみ map<__int64, __int64>::iterator itr; itr = rangeList.begin(); httpResHeader.insert(pair<string, string>("Content-Type", contentType)); Format(buff, "bytes %I64d-%I64d/%I64d", itr->first, itr->second, fileSize); httpResHeader.insert(pair<string, string>("Content-Range", buff)); Format(buff, "%I64d", itr->second-itr->first+1); httpResHeader.insert(pair<string, string>("Content-Length", buff)); httpSend.SendResponseHeader(206, &httpResHeader, clientSock, stopEvent); httpSend.SendFile(filePath, itr->first, itr->second+1, clientSock, stopEvent); } } } return ret; Err_End: httpSend.SendResponseHeader(ret, &httpResHeader, clientSock, stopEvent); End: return ret; }