📄 chttpsocketengine.cpp
字号:
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 + -