summaryrefslogtreecommitdiff
path: root/plugins/!NotAdopted/HTTPServer/HttpUser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/!NotAdopted/HTTPServer/HttpUser.cpp')
-rw-r--r--plugins/!NotAdopted/HTTPServer/HttpUser.cpp896
1 files changed, 0 insertions, 896 deletions
diff --git a/plugins/!NotAdopted/HTTPServer/HttpUser.cpp b/plugins/!NotAdopted/HTTPServer/HttpUser.cpp
deleted file mode 100644
index 0e06e39fd0..0000000000
--- a/plugins/!NotAdopted/HTTPServer/HttpUser.cpp
+++ /dev/null
@@ -1,896 +0,0 @@
-//This file is part of HTTPServer a Miranda IM plugin
-//Copyright (C)2002 Kennet Nielsen
-//
-//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 2 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, write to the Free Software
-//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-#include "HttpUser.h"
-#include "MimeHandling.h"
-#include "GuiElements.h"
-#include "IndexCreation.h"
-
-#include "Glob.h"
-#include <stdio.h>
-#include <time.h>
-
-
-/////////////////////////////////////////////////////////////////////
-// Member Function : FileTimeToUnixTime
-// Type : Global
-// Parameters : pft - ?
-// t - ?
-// Returns : void
-// Description :
-//
-// References : -
-// Remarks : -
-// Created : 030826, 26 august 2003
-// Developer : KN
-/////////////////////////////////////////////////////////////////////
-
-void FileTimeToUnixTime(LPFILETIME pft, time_t* t) {
- LONGLONG ll = ((LONGLONG)pft->dwHighDateTime) << 32;
- ll = ll + pft->dwLowDateTime - 116444736000000000;
- *t = (time_t)(ll / 10000000);
-}
-
-
-/////////////////////////////////////////////////////////////////////
-// Function : nUnescapedURI
-// Type : Local
-// Parameters : pszURI - URI to convert buffer is modifyed !!
-// Returns : length of the Unescaped URI
-// Description :
-//
-// References : -
-// Remarks : -
-// Created : 030911, 11 september 2003
-// Developer : KN
-/////////////////////////////////////////////////////////////////////
-
-static int nUnescapedURI(char * pszURI) {
- if (! pszURI)
- return 0;
-
- char * pszOrigURI = pszURI;
- int sumb;
- int more = -1;
- char* pszCurInsert = pszURI;
-
- for (; *pszURI && pszURI[0] != ' ' ; pszURI++) {
- int nNewChar;
- if (pszURI[0] == '%') {
- // we need to unescape the char
- if (pszURI[1] == NULL || pszURI[2] == NULL || pszURI[1] == ' ' || pszURI[2] == ' ')
- break; // handles error like "%2 " or "%a"
-
- if (sscanf(&pszURI[1], "%2X", &nNewChar) != 1) {
- // can't convert to number
- pszURI += 2;
- continue; // we skip it !!!
- }
- pszURI += 2;
- }
- /*else if( pszURI[0] == '+' )
- {
- nNewChar = ' ';
- }*/
- else
- nNewChar = (int)tolower(pszURI[0]); // also make the request lowercase
-
- if (nNewChar == '\\')
- nNewChar = '/';
-
- if ((nNewChar & 0x80) == 0x00) { // 0xxxxxxx (yields 7 bits)
- more = -1; // this is to avoid sequence like %C3k%A6 will end up beeing "kę" insted it will be "k"
- *pszCurInsert = (char)nNewChar;
- pszCurInsert++;
- continue;
- }
-
- if ((nNewChar & 0xc0) == 0x80) { // 10xxxxxx (continuation byte)
- sumb = (sumb << 6) | (nNewChar & 0x3f) ; // Add 6 bits to sumb
- more--;
- if (more == 0) {
- *pszCurInsert = (char)sumb; // here we just throw away all the fine UTF-8 encoding
- pszCurInsert++;
- }
- } else if ((nNewChar & 0xe0) == 0xc0) { // 110xxxxx (yields 5 bits)
- sumb = nNewChar & 0x1f;
- more = 1; // Expect 1 more byte
- } else if ((nNewChar & 0xf0) == 0xe0) { // 1110xxxx (yields 4 bits)
- sumb = nNewChar & 0x0f;
- more = 2; // Expect 2 more bytes
- } else if ((nNewChar & 0xf8) == 0xf0) { // 11110xxx (yields 3 bits)
- sumb = nNewChar & 0x07;
- more = 3; // Expect 3 more bytes
- } else if ((nNewChar & 0xfc) == 0xf8) { // 111110xx (yields 2 bits)
- sumb = nNewChar & 0x03;
- more = 4; // Expect 4 more bytes
- } else /*if ((nNewChar & 0xfe) == 0xfc)*/
- { // 1111110x (yields 1 bit)
- sumb = nNewChar & 0x01;
- more = 5; // Expect 5 more bytes
- }
- }
- return (pszCurInsert - pszOrigURI);
-}
-
-
-/////////////////////////////////////////////////////////////////////
-// Member Function : CLHttpUser
-// Type : Private / Public / Protected
-// Parameters : hCon - ?
-// stAdd - ?
-// pcl - ?
-// Returns :
-// Description :
-//
-// References : -
-// Remarks : -
-// Created : 030918, 18 september 2003
-// Developer : KN
-/////////////////////////////////////////////////////////////////////
-
-CLHttpUser::CLHttpUser(HANDLE hCon, in_addr stAdd) : CLShareUser(hCon, stAdd) {
- memset(apszParam, 0, sizeof(apszParam));
- hFile = INVALID_HANDLE_VALUE;
-}
-
-
-/////////////////////////////////////////////////////////////////////
-// Member Function : CLHttpUser
-// Type : Private / Public / Protected
-// Parameters : None
-// Returns :
-// Description :
-//
-// References : -
-// Remarks : -
-// Created : 031124, 24 november 2003
-// Developer : KN
-/////////////////////////////////////////////////////////////////////
-
-CLHttpUser::~CLHttpUser() {
- if (hFile != INVALID_HANDLE_VALUE)
- CloseHandle(hFile);
-}
-
-/////////////////////////////////////////////////////////////////////
-// Member Function : bReadGetParameters
-// Type : Private / Public / Protected
-// Parameters : pszRequest - ?
-// Returns : Returns true if
-// Description :
-//
-// References : -
-// Remarks : -
-// Created : 030928, 28 september 2003
-// Developer : KN
-/////////////////////////////////////////////////////////////////////
-
-bool CLHttpUser::bReadGetParameters(char * pszRequest) {
- bool bRet = true;
- for (; *pszRequest ; pszRequest++) {
- if (pszRequest[0] != '\n') {
- if (pszRequest[0] == '\r')
- pszRequest[0] = 0;
- continue;
- }
- pszRequest[0] = 0;
- pszRequest++;
- for (int nCur = 0; nCur < eLastParam ; nCur++) {
- int nLen = strlen(szParmStr[nCur]);
- if (strncmp(pszRequest, szParmStr[nCur], nLen) == 0) {
- if (apszParam[nCur]) {
- bRet = false;
- // already set !!
- } else {
- pszRequest += nLen;
- apszParam[nCur] = pszRequest;
- pszRequest += strcspn(pszRequest, "\r\n") - 1;
- char * psz = pszRequest;
- while (*psz == ' ') {
- psz[0] = 0;// owerwrite ' ' or '\r' or '\n'
- psz--;
- }
- }
- break;
- }
- }
- }
- return bRet;
-}
-
-/////////////////////////////////////////////////////////////////////
-// Member Function : SendError
-// Type : Private / Public / Protected
-// Parameters : iErrorCode - ?
-// pszError - ?
-// pszDescription - ?
-// Returns : void
-// Description :
-//
-// References : -
-// Remarks : -
-// Created : 031124, 24 november 2003
-// Developer : KN, Houdini
-// Changed : 21 January 2006 by Vampik
-/////////////////////////////////////////////////////////////////////
-
-void CLHttpUser::SendError(int iErrorCode, const char * pszError, const char * pszDescription) {
- char szCurTime[ 100 ];
- time_t ltime;
- time(&ltime);
- strftime(szCurTime, sizeof(szCurTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&ltime));
-
- if (!pszDescription)
- pszDescription = pszError;
-
- char szBuf[1000];
- DWORD dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf) ,
- "HTTP/1.1 %i %s\r\n"
- "Date: %s\r\n"
- "Server: MirandaWeb/%s\r\n"
- "Transfer-Encoding: chunked\r\n"
- "Content-Type: text/html; charset=iso-8859-1\r\n"
- "\r\n"
- "10f\r\n"
- "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
- "<HTML><HEAD>\n"
- "<TITLE>%i %s</TITLE>\n"
- "</HEAD><BODY>\n"
- "<H1>%s</H1>\n"
- "%s<P>\n"
- "<HR>\n"
- "<ADDRESS>MirandaWeb/%s</ADDRESS>\n"
- "</BODY></HTML>\n"
- "\r\n"
- "\r\n",
- iErrorCode, pszError, szCurTime, pszVersion, iErrorCode, pszError, pszError, pszDescription, pszVersion);
-
- Netlib_Send(hConnection, szBuf, dwBytesToWrite, 0);
-}
-
-/////////////////////////////////////////////////////////////////////
-// Member Function : SendRedir
-// Type : Private / Public / Protected
-// Parameters : iErrorCode - ?
-// pszError - ?
-// pszDescription - ?
-// pszRedirect - ?
-// Returns : void
-// Description :
-//
-// References : -
-// Remarks : -
-// Created : 21 january 2006
-// Developer : KN, Houdini, Vampik
-/////////////////////////////////////////////////////////////////////
-
-void CLHttpUser::SendRedir(int iErrorCode, const char * pszError, const char * pszDescription, const char * pszRedirect) {
- char szCurrTime[ 100 ];
- time_t ltime;
- time(&ltime);
- strftime(szCurrTime, sizeof(szCurrTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&ltime));
-
- if (!pszDescription)
- pszDescription = pszError;
-
- char szBuff[1000];
- DWORD dwBytesToWrite = _snprintf(szBuff, sizeof(szBuff) ,
- "HTTP/1.1 %i %s\r\n"
- "Date: %s\r\n"
- "Server: MirandaWeb/%s\r\n"
- "Location: %s/\r\n"
- "Transfer-Encoding: chunked\r\n"
- "Content-Type: text/html; charset=iso-8859-1\r\n"
- "\r\n"
- "10f\r\n"
- "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
- "<HTML><HEAD>\n"
- "<TITLE>%i %s</TITLE>\n"
- "</HEAD><BODY>\n"
- "<H1>%s</H1>\n"
- "%s<P>\n"
- "<HR>\n"
- "<ADDRESS>MirandaWeb/%s</ADDRESS>\n"
- "</BODY></HTML>\n"
- "\r\n"
- "\r\n",
- iErrorCode, pszError, szCurrTime, pszVersion, pszRedirect, iErrorCode, pszError, pszError, pszDescription, pszVersion);
-
- Netlib_Send(hConnection, szBuff, dwBytesToWrite, 0);
-}
-
-/////////////////////////////////////////////////////////////////////
-// Function : strmcat
-// Type : Local
-// Parameters : pszDest - ?
-// pszSrc - ?
-// MaxLength - ?
-// Returns :
-// Description : Fills pszDest until it is MaxLength long or
-// pszSrc is finished - always appends a \0
-// References : -
-// Remarks : -
-// Created :
-// Developer : Houdini
-/////////////////////////////////////////////////////////////////////
-
-static void strmcat(char* pszDest, const char* pszSrc, int iMaxLength) {
- int iLength = 0;
- while (*pszDest != '\0') {
- pszDest++;
- iLength++;
- }
-
- while (iLength < iMaxLength - 1 && *pszSrc != '\0') {
- *pszDest = *pszSrc;
- pszDest++;
- pszSrc++;
- iLength++;
- }
-
- *pszDest = '\0';
-}
-
-/////////////////////////////////////////////////////////////////////
-// Member Function : bProcessGetRequest
-// Type : Global
-// Parameters : hNewConnection - ?
-// dwRemoteIP - ?
-// pszRequest - ?
-// Returns : Returns true if a file was send
-// Description :
-//
-// References : -
-// Remarks : -
-// Created : 030813, 13 august 2003
-// Developer : KN, Houdini
-// Changed : 27 January 2005 by Vampik
-// Changed : 21 January 2006 by Vampik
-/////////////////////////////////////////////////////////////////////
-
-bool CLHttpUser::bProcessGetRequest(char * pszRequest, bool bIsGetCommand) {
- //LogEvent("Request", pszRequest);
-
- int nUriLength = nUnescapedURI(pszRequest);
- if (nUriLength <= 0)
- return false;
-
- CLFileShareListAccess clCritSection;
-
- if (bShutdownInProgress)
- return false;
-
- static char szTempfile[MAX_PATH+1];
- szTempfile[0] = '\0';
-
- if (!bReadGetParameters(pszRequest)) {
- SendError(400, "Bad Request");
- return false;
- }
-
- DWORD dwRemoteIP = ntohl(stAddr.S_un.S_addr);
- for (CLFileShareNode * pclCur = pclFirstNode; pclCur ; pclCur = pclCur->pclNext) {
- if ((pclCur->st.dwAllowedIP ^ dwRemoteIP) & pclCur->st.dwAllowedMask)
- continue; // Not an allowed IP address
-
- if (!pclCur->bIsDirectory() && pclCur->nGetSrvPathLen() != nUriLength)
- continue; // not the right length, quickly move on to the next.
-
- if (pclCur->bIsDirectory() ?
- (strncmp(pclCur->st.pszSrvPath, pszRequest, pclCur->nGetSrvPathLen() - 1) == 0) :
- (strncmp(pclCur->st.pszSrvPath, pszRequest, pclCur->nGetSrvPathLen()) == 0)) {
- /*OutputDebugString( "Request for file OK : ");
- OutputDebugString( pclCur->st.pszSrvPath );
- OutputDebugString( "\n" );*/
-
- static char szSrvPath[MAX_PATH+1];
- static char szRealPath[MAX_PATH+1];
- char* pszSrvPath = pclCur->st.pszSrvPath;
- char* pszRealPath = pclCur->st.pszRealPath;
-
- if (pclCur->bIsDirectory()) {
- strcpy(szRealPath, pclCur->st.pszRealPath);
- strcpy(szSrvPath, pclCur->st.pszSrvPath);
- pszRealPath = szRealPath;
- pszSrvPath = szSrvPath;
-
- if (nUriLength > MAX_PATH)
- nUriLength = MAX_PATH;
-
- pszRequest[nUriLength] = '\0';
-
- if (pclCur->nGetSrvPathLen() - nUriLength == 1) {
- SendRedir(302, "Found", "The document has moved", pszRequest);
- return false;
- } else {
- strmcat(pszRealPath, &pszRequest[pclCur->nGetSrvPathLen()], MAX_PATH);
- strmcat(pszSrvPath, &pszRequest[pclCur->nGetSrvPathLen()], MAX_PATH);
- }
- pszRequest[nUriLength] = ' ';
-
- // hacker protection - should be removed by the browser
- if (strstr(pszRealPath, "..")) {
- SendError(404, "Not Found", "The requested URL was not found on this server.");
- return false;
- }
-
- char* pszTmp = pszRealPath;
- while (pszTmp = strchr(pszTmp, '/'))
- * pszTmp = '\\';
-
- hFile = CreateFile(pszRealPath, GENERIC_READ ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (hFile == INVALID_HANDLE_VALUE) {
- if (pszSrvPath[strlen(pszSrvPath)-1] != '/') {
- strmcat(pszRealPath, "\\", MAX_PATH);
- strmcat(pszSrvPath, "/", MAX_PATH);
- }
-
- // a directory with index.htm
- strmcat(szRealPath, "index.htm", MAX_PATH);
-
- hFile = CreateFile(pszRealPath, GENERIC_READ ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_HIDDEN, NULL);
-
- if (hFile == INVALID_HANDLE_VALUE) {
- // a directory with index.html
- strmcat(szRealPath, "l", MAX_PATH);
-
- hFile = CreateFile(pszRealPath, GENERIC_READ ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_HIDDEN, NULL);
-
- if (hFile == INVALID_HANDLE_VALUE) {
- // generate directory index in temporary file
- if (*szTempfile == '\0') {
- GetTempPath(MAX_PATH, szTempfile);
- strmcat(szTempfile, "\\HttpServerTemp", MAX_PATH);
- strmcat(szTempfile, pszSrvPath, MAX_PATH);
- char* pszTmp = szTempfile;
- while (pszTmp = strchr(pszTmp, '/'))
- * pszTmp = '~';
- }
- pszRealPath[strlen(pszRealPath) - 10] = '\0';
-
- // detecting browser function removed
- // every browser should support it by now
- bool BrowserSupportsXML = true;
- //(apszParam[eUserAgent] != NULL) &&
- // (strstr(apszParam[eUserAgent], "Firefox") ||
- // (strstr(apszParam[eUserAgent], "MSIE") && !strstr(apszParam[eUserAgent], "Opera")));
-
- if ((indexCreationMode == INDEX_CREATION_XML ||
- (indexCreationMode == INDEX_CREATION_DETECT && BrowserSupportsXML)) &&
- bCreateIndexXML(pszRealPath, szTempfile, pszSrvPath, dwRemoteIP)) {
- hFile = CreateFile(szTempfile, GENERIC_READ ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
- strcpy(szRealPath, "a.xml"); // restore .xml for mime type
- } else if ((indexCreationMode == INDEX_CREATION_HTML ||
- indexCreationMode == INDEX_CREATION_DETECT) &&
- bCreateIndexHTML(pszRealPath, szTempfile, pszSrvPath, dwRemoteIP)) {
- hFile = CreateFile(szTempfile, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
- strcpy(szRealPath, "a.html"); // restore .html for mime type
- } else {
- continue;
- }
- } else {
- strmcat(pszSrvPath, "index.html", MAX_PATH);
- szTempfile[0] = '\0';
- }
- } else {
- strmcat(pszSrvPath, "index.htm", MAX_PATH);
- szTempfile[0] = '\0';
- }
- } else {
- szTempfile[0] = '\0';
- }
- } else {
- hFile = CreateFile(pszRealPath, GENERIC_READ ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (hFile == INVALID_HANDLE_VALUE) {
- SendError(404, "Not Found", "HTTP server failed to open local file");
- return false;
- }
- }
-
- strcpy(this->szCurrentDLSrvPath, pszSrvPath);
-
- DWORD nDataSize = GetFileSize(hFile, NULL);
- dwTotalSize = nDataSize;
-
- FILETIME stFileTime;
- GetFileTime(hFile, NULL, NULL, &stFileTime);
-
- char szCurTime[ 100 ];
- time_t ltime;
- time(&ltime);
- strftime(szCurTime, sizeof(szCurTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&ltime));
-
- char szFileTime[ 100 ];
- FileTimeToUnixTime(&stFileTime, &ltime);
- strftime(szFileTime, sizeof(szFileTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&ltime));
-
- if (apszParam[eIfModifiedSince] && strcmp(apszParam[eIfModifiedSince], szFileTime) == 0) {
- SendError(304, "Not Modified" );
- return true;
- }
-
- // we found match send file !!
- if (bIsGetCommand) {
- if (! pclCur->bAddUser(this)) {
- SendError(403, "Forbidden", "Access has been denied because there are too many connections");
- return false;
- }
- }
-
- if (*(ULONG*)(&stAddr) != 0x0100007F && // do not show popup of 127.0.0.1
- strstr(pszRealPath, "\\@") == NULL) { // and of shares which start with an @
- ShowPopupWindow(inet_ntoa(stAddr), pszSrvPath);
- }
-
- clCritSection.Unlock();
-
- DWORD dwFileStart = 0;
- DWORD dwDataToSend = nDataSize;
-
- char szETag[ 50 ];
- {
- int nETagLen = _snprintf(szETag, sizeof(szETag), "\"%x-%x-%x\"",
- nDataSize, stFileTime.dwHighDateTime, stFileTime.dwLowDateTime);
-
- if (!apszParam[eIfRange] || (strncmp(szETag, apszParam[eIfRange], nETagLen) == 0)) {
- char * pszRange = apszParam[eRange];
- if (pszRange) {
- if (strncmp(pszRange, "bytes=", 6) == 0) {
- pszRange += 6;
- // Do resume !!!
- char *pszEnd;
- if (pszRange[0] == '-') {
- // its a suffix-byte-range-spec
- DWORD dwLen = strtol(pszRange + 1, &pszEnd, 10);
- if (dwLen < nDataSize)
- dwFileStart = nDataSize - dwLen;
- } else {
- DWORD dwLen = strtol(pszRange, &pszEnd, 10);
- if (*pszEnd == '-' && dwLen < nDataSize) {
- dwFileStart = dwLen;
- pszRange = pszEnd + 1;
- if (*pszRange != 0) {
- dwLen = strtol(pszEnd + 1, &pszEnd, 10);
- if (dwLen > dwFileStart)
- dwDataToSend = (dwLen + 1) - dwFileStart;
- else
- dwFileStart = 0;
- }
- } else {
- SendError(400, "Bad Request");
- return false;
- }
- }
- }
- }
- }
- }
-
- if (dwFileStart >= nDataSize)
- dwFileStart = 0;
-
- if (dwFileStart + dwDataToSend >= nDataSize)
- dwDataToSend = nDataSize - dwFileStart;
-
-
- DWORD dwBytesToWrite = 0;
- // To optimize send speed it it ideal to always send larges size packages
- // But this size depended on network media but on Ethernet it is 1518 bytes.
- // Ethernet, IP and TCP headers use some of this space and leaves 1460 bytes
- // for data transfer.
- // We will use a multiply of this to always send optimal sized packages.
- char szBuf[1460 * 4];
-
- if (dwFileStart > 0 || dwDataToSend != nDataSize) {
- if (SetFilePointer(hFile, dwFileStart, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
- SendError(416, "Requested Range Not Satisfiable");
- return true;
- }
-
- const char szHttpPartial[] = "HTTP/1.1 206 Partial Content\r\n"
- "Connection: Keep-Alive\r\n"
- "Date: %s\r\n"
- "Server: MirandaWeb/%s\r\n"
- "Accept-Ranges: bytes\r\n"
- "ETag: %s\r\n"
- "Content-Length: %d\r\n"
- "Content-Type: %s\r\n"
- "Content-Range: bytes %d-%d/%d\r\n"
- "Last-Modified: %s\r\n"
- "\r\n";
-
- dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf), szHttpPartial ,
- szCurTime ,
- pszVersion,
- szETag ,
- dwDataToSend ,
- pszGetMimeType(pszRealPath),
- dwFileStart,
- (dwFileStart + dwDataToSend - 1),
- nDataSize,
- szFileTime);
- } else {
- const char szHttpOk[] = "HTTP/1.1 200 OK\r\n"
- "Connection: Keep-Alive\r\n"
- "Date: %s\r\n"
- "Server: MirandaWeb/%s\r\n"
- "Accept-Ranges: bytes\r\n"
- "ETag: %s\r\n"
- "Content-Length: %d\r\n"
- "Content-Type: %s\r\n"
- "Last-Modified: %s\r\n"
- "\r\n";
-
- dwBytesToWrite = _snprintf(szBuf, sizeof(szBuf), szHttpOk ,
- szCurTime ,
- pszVersion,
- szETag ,
- nDataSize ,
- pszGetMimeType(pszRealPath),
- szFileTime);
- }
-
- Netlib_Send(hConnection, szBuf, dwBytesToWrite, 0);
-
- if (bIsGetCommand) {
- static int nThreadCount = 0;
- nThreadCount++;
-
- DWORD dwLastUpdate = GetTickCount();
- DWORD dwLastCurrentDL = 0;
- /*
-
- dwLastDLSTickCount = dwCurTick;
- dwCurrentDL;*/
-
- //DWORD dwMaxSpeed = 8192;// Byte pr Sek
- //DWORD dwMaxSpeed = 20000;// Byte pr Sek
- //DWORD dwMaxSpeed = 163840;// Byte pr Sek
- //DWORD dwMaxSpeed = 4096;// Byte pr Sek
-
- DWORD dwLastResetTime = GetTickCount();
- int nMaxBytesToSend = nMaxUploadSpeed / nThreadCount;
-
- for (;;) {
- {
- DWORD dwCurTick = GetTickCount();
- if (dwCurTick - dwLastUpdate >= 1000) {/*
- char szTmp[200];
- _snprintf( szTmp, sizeof( szTmp ), "Bytes tr %d Time %d Tick %d\n", dwCurrentDL - dwLastCurrentDL, dwCurTick - dwLastUpdate, dwCurTick );
- OutputDebugString( szTmp );
- */
- dwSpeed = ((dwCurrentDL - dwLastCurrentDL) * 1000) / (dwCurTick - dwLastUpdate);
- dwLastUpdate = dwCurTick;
- dwLastCurrentDL = dwCurrentDL;
- }
- }
-
- if (nMaxUploadSpeed == 0) {
- Sleep(1000);
- continue;
- }
-
- bool bSpeedLimit = (nMaxUploadSpeed >= 0) && (bIsOnline || !bLimitOnlyWhenOnline);
-
- DWORD dwCurOpr = sizeof(szBuf);
- if (bSpeedLimit)
- dwCurOpr = min(nMaxBytesToSend, sizeof(szBuf));
-
- if (!ReadFile(hFile, szBuf, dwCurOpr, &dwBytesToWrite, NULL))
- break;
-
- if (dwBytesToWrite <= 0)
- break;
-
- if (dwCurrentDL + dwBytesToWrite > dwDataToSend)
- dwBytesToWrite = dwDataToSend - dwCurrentDL;
-
- if (bSpeedLimit)
- nMaxBytesToSend -= dwBytesToWrite;
-
- DWORD dwSend = Netlib_Send(hConnection, szBuf, dwBytesToWrite, MSG_NODUMP);
- if (dwSend == SOCKET_ERROR)
- break;
- dwCurrentDL += dwSend;
- if (dwSend != dwBytesToWrite)
- break;
-
- if (dwCurrentDL >= dwDataToSend)
- break;
-
- if (bSpeedLimit && nMaxBytesToSend <= 0) {
- // we have reached the limmit
- DWORD dwTimeUsed = GetTickCount() - dwLastResetTime;
- if (dwTimeUsed < 1000)
- Sleep(1000 - dwTimeUsed);
- dwLastResetTime = GetTickCount();
- nMaxBytesToSend = nMaxUploadSpeed / nThreadCount;
- }
- /*
- char szTmp[200];
- _snprintf( szTmp, sizeof( szTmp ), "Current status : %d %% pos %d size %d\n", (dwCurrentDL * 100) / dwTotalSize, dwCurrentDL , dwTotalSize );
- OutputDebugString( szTmp );
- */
- }
-
- // file is always closed in destructor
- if (szTempfile[0] != '\0') {
- // and here - since it is a temporary index which as to be deleted
- CloseHandle(hFile);
- hFile = INVALID_HANDLE_VALUE;
-
- DeleteFile(szTempfile);
- }
- /*
- {
- char szBuf[200];
- _snprintf( szBuf, sizeof( szBuf ), "File Transfer stoped %d transfer complete %d\n", GetTickCount(), dwCurrentDL == nDataSize);
- OutputDebugString( szBuf );
- }
- */
- clCritSection.Lock();
- nThreadCount--;
-
- bool bNeedToWriteConfig = false;
-
- if (dwCurrentDL == nDataSize) {
- if (pclCur->st.nMaxDownloads > 0) {
- pclCur->st.nMaxDownloads--;
- bNeedToWriteConfig = true;
- }
- }
-
- pclCur->bRemoveUser(this);
-
- // nMaxDownloads can have been decreesed by another thread.
- // Therefore we test it even if we did'en decreese it
- if (pclCur->st.nMaxDownloads == 0 && !pclCur->bAnyUsers()) {
- CLFileShareNode **pclPrev = &pclFirstNode;
- for (CLFileShareNode * pcl = pclFirstNode ; pcl ; pcl = pcl->pclNext) {
- if (pcl == pclCur) {
- *pclPrev = pclCur->pclNext;
- ShowPopupWindow(Translate("Share removed"), pclCur->st.pszSrvPath, RGB(255, 189, 189));
- delete pclCur;
- bNeedToWriteConfig = true;
- break;
- }
- pclPrev = &pcl->pclNext;
- }
- }
-
- if (bNeedToWriteConfig) {
- bWriteConfigurationFile();
- }
- }
-
- return true;
- }
- }
-
-
-#ifdef _DEBUG
- OutputDebugString("########### Request Failed ###########\n");
- OutputDebugString(pszRequest);
-#endif
-
- pszRequest[nUriLength] = 0;
-
- if ((nUriLength != 12 || strncmp(pszRequest, "/favicon.ico", nUriLength)) && // do not show popup of favicon.ico
- *(ULONG*)(&stAddr) != 0x0100007F) { // do not show popup of 127.0.0.1
- ShowPopupWindow(inet_ntoa(stAddr), pszRequest, RGB(255, 189, 189));
- }
-
- SendError(404, "Not Found", "The requested URL was not found on this server.");
-
- return false;
-}
-
-
-void CLHttpUser::HandleNewConnection() {
-
-/*
- {
- SOCKET s = CallService(MS_NETLIB_GETSOCKET, (WPARAM) hConnection, 0);
- sockaddr_in MyAddr;
- int nSize = sizeof( MyAddr );
- getsockname( s, (sockaddr*)&MyAddr, &nSize );
- ShowPopupWindow( "My IP address", inet_ntoa( MyAddr.sin_addr ) );
- //OutputDebugString( );
- }*/
- /*
- {
- LINGER li;
- int nLenght = sizeof( li );
- int ret = getsockopt( s, IPPROTO_TCP, SO_LINGER, (char *)&li, &nLenght );
- if( ret )
- {
- DWORD error = WSAGetLastError();
- if( error
- WSANOTINITIALISED
- WSAENETDOWN The network subsystem has failed.
- WSAEFAULT One of the optval or the optlen parameters is not a valid part of the user address space, or the optlen parameter is too small.
- WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
- WSAEINVAL The level parameter is unknown or invalid.
- WSAENOPROTOOPT The option is unknown or unsupported by the indicated protocol family.
- WSAENOTSOCK
- }
- nLenght = sizeof( li );
- li.l_onoff = 1;
- li.l_linger = 0;// time is default
- ret = setsockopt( s, IPPROTO_TCP, SO_LINGER, (const char *)&li, nLenght );
- if( ret )
- {
- // error
- }
- int nLenght = sizeof( li );
- int ret = getsockopt( s, IPPROTO_TCP, SO_LINGER, (char *)&li, &nLenght );
- }
- */
-
- char szBuf[1000];
- int nCurPos = 0;
- while (sizeof(szBuf) - nCurPos > 10 && !bShutdownInProgress) {
- int nBytesRead = Netlib_Recv(hConnection, &szBuf[nCurPos], sizeof(szBuf) - nCurPos, 0);
- if (! nBytesRead) {
- // socket closed gracefully
- break;
- }
- if (nBytesRead == SOCKET_ERROR) {
- // socket closed with error
- // WSAGetLastError();
- break;
- }
- int nOldCurPos = nCurPos;
- nCurPos += nBytesRead;
- if (nCurPos <= 5)
- continue;
-
- bool bIsGetCommand = memcmp(szBuf, "GET ", 4) == 0;
- if (!bIsGetCommand && memcmp(szBuf, "HEAD ", 5) != 0) {
- SendError(501, "Not Implemented");
- break; // We only support GET and HEAD commands !!
- }
-
- if (nOldCurPos < 4)
- nOldCurPos = 4; // scan forward from end of "GET " to locate the next space ' '
-
- bool bBreakWhile = false;
- for (; nOldCurPos < nCurPos; nOldCurPos++) {
- if (szBuf[nOldCurPos-2] == '\n' && szBuf[nOldCurPos-1] == '\r' && szBuf[nOldCurPos] == '\n') {
- // we have a walid request !!! scan to see if we have this file
- szBuf[nOldCurPos] = NULL;
- bProcessGetRequest(&szBuf[bIsGetCommand?4:5], bIsGetCommand);
-
- bBreakWhile = true;
- break;
- }
- }
- if (bBreakWhile)
- break;
- }
-}