/// <summary> /// Runs the server in its own Thread. /// </summary> private void ThreadMain() { Exception workException = null; try { Debug.Print("Accepted Socket, workerid: " + this.WorkerID.ToString()); _SocketAcceptedHandler(this); if (_ConnectionSocket.Poll(-1, SelectMode.SelectRead)) { // Create buffer and receive raw bytes. byte[] firstLanPacket = new byte[_LanPacketByteCount]; int count = 0; SocketFlags socketFlags = new SocketFlags(); count = _ConnectionSocket.Receive(firstLanPacket, count, _ConnectionSocket.Available - count, socketFlags); if (firstLanPacket[0] == 0) { Debug.Print("empty request, count: " + count.ToString()); workException = new Exception("Empty Packet found" + this.WorkerID.ToString());// exception not thrown just sent back } else { string rawHeader = new string(Encoding.UTF8.GetChars(firstLanPacket)); Hashtable headerFields = null; int contentStart = -1; EnumRequestType requestType = EnumRequestType.Get;// check for get first BaseRequest.LoadHeader(firstLanPacket, count, out contentStart, out headerFields, out requestType); BaseRequest request = null; try { if (requestType == EnumRequestType.Get) { request = new BaseRequest(firstLanPacket, count, 0, headerFields, requestType);// no content } else { if (requestType == EnumRequestType.Post) { request = new PostRequest(firstLanPacket, count, 0, headerFields, requestType, _ConnectionSocket, GetMoreBytes);// todo put delegate } else { throw new NotImplementedException("Http PUT is not implemented."); } } } catch (Exception ex) { //return server 500; workException = ex; SendErrorResponse(_ConnectionSocket, SupportedErrors.ServerError, request, ex, this.WorkerID); request = null; } // ConsoleWrite.CollectMemoryAndPrint(true, this.WorkerID); //requestQueue.Enqueue(request);todo if (request != null) { string requestMimeType = GetMimeType(request.Uri); Debug.Print("Request MIME Type: " + requestMimeType); if (requestMimeType.Length > 0) { // file request try { string fullFilePath = SDCard.GetFullPathFromUri(request.BaseUri); Debug.Print("File Request received:" + fullFilePath); // send start long fileSize = SDCard.GetFileSize(fullFilePath); if (fileSize > 0) { int maxAge = GetMaxAgeFromMimeType(requestMimeType); string header = HttpGeneral.GetHttpHeader(fileSize, requestMimeType, maxAge); byte[] returnBytes = Encoding.UTF8.GetBytes(header); _ConnectionSocket.Send(returnBytes, returnBytes.Length, SocketFlags.None); SDCard.ReadInChunks(fullFilePath, _ConnectionSocket);// boolean result doesnt really do much so ignore. } else { SendErrorResponse(_ConnectionSocket, SupportedErrors.FileNotFound, request, null, this.WorkerID); } } catch (Exception ex) { //return server 500; workException = ex; SendErrorResponse(_ConnectionSocket, SupportedErrors.ServerError, request, ex, this.WorkerID); } } else {// page request if (_ResponseHandler != null) { try { string response = _ResponseHandler(request); byte[] returnBytes = Encoding.UTF8.GetBytes(response); _ConnectionSocket.Send(returnBytes, 0, returnBytes.Length, SocketFlags.None); } catch (Exception ex) { //return server 500; workException = ex; SendErrorResponse(_ConnectionSocket, SupportedErrors.ServerError, request, ex, this.WorkerID); } } } } } } }// using statement can throw in the dispose. catch (Exception ex) { workException = ex; Debug.Print("Exception, workerid: " + this.WorkerID.ToString() + ", ex: " + ex.Message); } finally { if (_ConnectionSocket != null) { ((IDisposable)_ConnectionSocket).Dispose(); } _WorkFinishedHandler(workException, this); } }
private void SendErrorResponse(Socket connectionSocket, SupportedErrors errorType, BaseRequest request, Exception ex, int workerID) { string errorTypeText = ""; if (errorType == SupportedErrors.ServerError) { errorTypeText = "500 Server Error"; Debug.Print("SendErrorResponse, workerid: " + workerID.ToString() + ", ex: " + ex.Message + " " + errorTypeText); } else { errorTypeText = "404 File not found"; Debug.Print("SendErrorResponse, workerid: " + workerID.ToString() + " " + errorTypeText); } string header = ""; string content = HtmlGeneral.HtmlStart + "<h1>" + errorTypeText + "</h1>" + "<h3>Uri: " + request.Uri + "</h3>"; if (ex != null) { content += "<p>Error: " + ex.Message + "</p>"; } content += HtmlGeneral.HtmlEnd; if (errorType == SupportedErrors.ServerError) { header = HttpGeneral.Get500Header(content.Length); } else { header = HttpGeneral.Get404Header(content.Length); } byte[] returnBytes = Encoding.UTF8.GetBytes(header + content); connectionSocket.Send(returnBytes, 0, returnBytes.Length, SocketFlags.None); }