⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chttpsocketengine.cpp

📁 Symbian手机上一个简单的http server 服务器代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		if (linebuf.Length() + readbuf.Length() < MAXLINELEN)
		{
			// There's room. Just append.
			linebuf.Append(readbuf);
		}
		else
		{
			// Not enough room. But there might be a newline in readbuf.
			pos = readbuf.Locate('\n');
			if (pos == KErrNotFound)
			{
				// No newline and too much data.
				// Return as much as possible,
				// then buffer as much as possible,
				// and discard the rest.
				
				buf.Copy(linebuf);
				linebuf.Copy(readbuf);
				readbuf.SetLength(MAXLINELEN - buf.Length());
				buf.Append(readbuf);
				linebuf.Delete(0, readbuf.Length());
				return ETrue;
			}
			else
			{
				// A newline was found.
				// Return linebuf and as much as possible
				// of readbuf (until the newline),
				// then buffer everything after the newline.
				
				buf.Copy(linebuf);
				chunk = MAXLINELEN - buf.Length();
				if (pos <= chunk)
				{
					// Everything fits.
					linebuf.Copy(readbuf);
					linebuf.SetLength(pos);
					if (linebuf.Length() > 0 && linebuf[linebuf.Length()-1] == '\r') linebuf.SetLength(linebuf.Length()-1);
					buf.Append(linebuf);
					linebuf.Copy(readbuf);
					linebuf.Delete(0, pos+1);
				}
				else
				{
					// Won't fit, truncate.
					linebuf.Copy(readbuf);
					linebuf.SetLength(chunk);
					buf.Append(linebuf);
					linebuf.Copy(readbuf);
					linebuf.Delete(0, pos+1);
				}
				return ETrue;
			}
		}
	}
}

void CHttpSocketEngine::HandleClientL(RSocket &client)
{
	int row = 0;
	TInt spacepos1;
	TInt spacepos2;
	TBool chunked = EFalse;
	TInt contentlength = -1;
	TInt i;
	
	// Read HTTP request and headers
	while (ReadLine(client, buf) && buf.Length() > 0)
	{
		// Show some debugging info
		debug.SetLength(0);
		for (i = 0; i < buf.Length(); i++) debug.Append(buf[i]);
		view->PrintL(debug);
		
		if (row++ == 0)
		{
			// Request line: "GET /url/path HTTP/1.1"
			request.Copy(buf);
		}
		else
		{
			// Header: Value
			
			if (buf.Left(((TDesC &) KTransferEncoding).Length()).Compare(KTransferEncoding) == 0)
			{
				if (buf.Right(((TDesC &) KChunked).Length()).Compare(KChunked) == 0)
				{
					chunked = ETrue;
				}
			}
			else if (buf.Left(((TDesC8 &) KContentLength).Length()).Compare(KContentLength) == 0)
			{
				spacepos1 = ((TDesC8 &)KContentLength).Length();
				while (spacepos1 < buf.Length() && buf[spacepos1] == ' ') spacepos1++;
				TLex8 lex(buf.Mid(spacepos1));
				lex.Val(contentlength);
			}
		}
	}
	
	// Parse HTTP request line
	
	spacepos1 = request.Locate(' ');
	spacepos2 = request.LocateReverse(' ');
	
	if (spacepos1 >= 0)
	{
		if (spacepos2 <= spacepos1 || spacepos2 < 0)
		{
			// Just one space. URL starts at spacepos1+1.
			buf.Copy(request);
			buf.Delete(spacepos1, buf.Length()-spacepos1);
			request.Delete(0, spacepos1+1);
		}
		else
		{
			// Two spaces. URL is from spacepos1+1 to spacepos2-1.
			buf.Copy(request);
			buf.Delete(spacepos1, buf.Length()-spacepos1);
			request.Delete(spacepos2, request.Length()-spacepos2);
			request.Delete(0, spacepos1+1);
		}
		ProcessRequestL(client, buf, request, contentlength, chunked);
	}
	else
	{
		// No space found.
		SendResponse(client, K400BadRequest);
	}
	
	// The connection is closed automatically when this function exits.
}

void CHttpSocketEngine::SendResponse(RSocket &client, const TDesC8 &response)
{
	TRequestStatus status;
	
	client.Write(response, status);
	User::WaitForRequest(status);
}

void CHttpSocketEngine::ProcessRequestL(RSocket &client, TDesC8 &method, TDesC8 &url, TInt contentlength, TBool chunked)
{
	TRequestStatus status;
	TBuf8 <128> resp;
	TBuf8 <256> content;
	TInt downloaded = 0;
	TInt chunk;
	TInt nr;
	
	// Show some debugging info in the log
	
	/*
	debug.SetLength(0);
	for (i = 0; i < method.Length(); i++) debug.Append(method[i]);
	debug.Append(' ');
	for (i = 0; i < url.Length(); i++) debug.Append(url[i]);
	view->PrintL(debug);
	
	debug.Format(_L("Content-Length: %d"), contentlength);
	view->PrintL(debug);
	
	if (chunked) view->PrintL(KTransferEncodingChunked);
	*/
	
	// If there is a request body, read it now.
	
	if (contentlength > 0)
	{
		if (chunked)
		{
			// Read chunked data.
			
			debug.Format(KReceivingChunkedFormat, contentlength);
			view->PrintL(debug);
			
			while ((chunk = ReadChunkSize(client)) > 0)
			{
				debug.Format(KReadingChunkFormat, chunk);
				view->PrintL(debug);
				
				while (chunk > 0)
				{
					chunk = ReadChunk(client, chunk, buf);
					// Now buf contains the data we read
					downloaded += buf.Length();
				}
			}
		}
		else
		{
			// Read straight data.
			
			debug.Format(KReceivingStraightFormat, contentlength);
			view->PrintL(debug);
			
			while (downloaded < contentlength && (nr = ReadBuffer(client, buf)) > 0)
			{
				// Now buf contains the data we read
				downloaded += nr;
			}
		}
	}
	
	// Now we can check what the URL points to and return the result.
	// To return static content, store it in the <content> variable.
	
	if (url.Compare(KBtBridge) == 0)
	{
		// Return data from the Bluetooth Bridge
		
		content.Copy(_L("<html><body><h2>BLUETOOTH DATA</h2><p>This is Bluetooth data</p></body></html>"));
	}
	else if (ReadFileL(url, content))
	{
		// Send content from file.
	}
	else
	{
		// Unrecognized URL
		SendResponse(client, K404NotFound);
		return;
	}
	
	// Send OK response
	resp.Format(K200ResponseFormat, content.Length());
	client.Write(resp, status);
	User::WaitForRequest(status);
	client.Write(content, status);
	User::WaitForRequest(status);
}

TBool CHttpSocketEngine::ReadFileL(const TDesC8 &relpath, TDes8 &content)
{
	RFs fs;
	RFile file;
	TBuf <256> path;
	TBuf8 <256> buf;
	_LIT(KHtdocs, "htdocs\\");
	TInt pos;
	TInt err;
	TInt i;
	
	fs.Connect();
	
	// Form the base path from our application directory.
	path.Copy(appui->Application()->AppFullName());
	pos = path.LocateReverse('\\');
	if (pos > 0) path.Delete(pos+1, path.Length()-pos-1);
	path.Append(KHtdocs);
	pos = path.Length();
	for (i = 0; i < relpath.Length(); i++)
	{
		if (i == 0 && relpath[i] == '/') continue; // Skip initial slash
		path.Append(relpath[i]);
	}
	
	// Clean up unallowed chars
	for (; pos < path.Length(); pos++)
	{
		if (!('a' <= path[pos] && path[pos] <= 'z')
		 && !('A' <= path[pos] && path[pos] <= 'Z')
		 && !('0' <= path[pos] && path[pos] <= '9')
		 && path[pos] != '-' && path[pos] != '_'
		 && path[pos] != '.' && path[pos] != '/')
		{
			// Illegal chars become underscores
			path[pos] = '_';
		}
		else if (path[pos] == '/')
		{
			// Change slash to backslash or Symbian paths
			path[pos] = '\\';
		}
		else if (pos > 0 && path[pos-1] == '.' && path[pos] == '.')
		{
			// Two consecutive dots can't be allowed
			path[pos-1] = '_';
			path[pos] = '_';
		}
	}
	
	// Remove trailing slashes, some browsers make these.
	while (path.Length() > 0 && path[path.Length()-1] == '/')
	{
		path.SetLength(path.Length()-1);
	}
	
	view->PrintL(path);
	
	// See if we can open the file.
	
	err = file.Open(fs, path, EFileRead);
	if (err != KErrNone)
	{
		// File not found
		fs.Close();
		return EFalse;
	}
	
	while (file.Read(buf) == KErrNone && buf.Length() > 0)
	{
		content.Append(buf);
	}
	
	file.Close();
	
	fs.Close();
	
	return ETrue;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -