/// <summary> /// Sends the request and waits for a response /// </summary> /// <param name="request">The request to be processed by the server and for which we want a response.</param> /// <returns></returns> public virtual HttpResponse GetResponse( HttpRequest request, HttpMessageProgressEventHandler onSendProgress, HttpMessageProgressEventHandler onRecvProgress, object stateObject) { try { // send the request this.SendRequest(request, onSendProgress, stateObject); // lock the reader HttpResponse response = null; lock(_messageReader) { // receive the response HttpMessage message = _messageReader.Read(_socket, null, onRecvProgress, stateObject); if (message.Type == HttpMessageTypes.HttpResponse) response = new HttpResponse(message); } if (response != null) { Debug.WriteLineIf(_verbose, "Logging response...", MY_TRACE_CATEGORY); Debug.WriteIf(_verbose, response.ToString(false)); } return response; } catch(Exception ex) { // notify that this connection has encountered an exception this.OnException(this, new ExceptionEventArgs(ex)); this.Close(); } return null; }
/// <summary> /// Sends the specified response using the connection's socket /// </summary> /// <param name="response"></param> public virtual void SendResponseToRequest(ref HttpRequest request, ref HttpResponse response) { try { // if the request has asked that the connection be kept-alive, we'll abide by the request if (HttpUtils.Contains(request.Connection, HttpConnections.KeepAlive)) // so instruct the response to notify the user-agent that the connection will be kept alive response.Connection = HttpConnections.KeepAlive; Debug.WriteLineIf(_verbose, "Sending response...", MY_TRACE_CATEGORY); Debug.WriteIf(_verbose, response.ToString(false)); // lock the writer lock(_messageWriter) { // send the message _messageWriter.Write(_socket, null, response); } // next check the request to see if the connection should be closed after the response was sent if (HttpUtils.Contains(request.Connection, HttpConnections.Close)) { // yup, they wanted us to close the connection automatically so lets do that now this.Close(); return; } } catch(ThreadAbortException) { } catch(Exception ex) { throw new Exception(ex.Message, ex); } /* * the following demonstrates a bug in the binary writer, or else some encoding issues with the message class' ToByteArray(.,.) method * */ // sending it all at once works... // _socket.Send(response.ToByteArray()); // byte[] all = response.ToByteArray(true, true); // byte[] headers = response.ToByteArray(true, false); // byte[] body = response.ToByteArray(false, true); // byte[] none = response.ToByteArray(false, false); //// // Debug.WriteLine(string.Format("Sending message... All '{0}', Combined '{1}', Headers '{2}', Body '{3}'", all.Length, headers.Length + body.Length, headers.Length, body.Length)); // Debug.WriteLine(string.Format("\t...A diference of '{0}'", (headers.Length + body.Length) - all.Length)); // //// _socket.Send(all); // _socket.Send(headers); // _socket.Send(body); }
/// <summary> /// Checks the headers of a response message /// </summary> /// <param name="response"></param> internal protected void CheckRequiredResponseHeaders(HttpResponse response) { // make sure the server header is filled in if (HttpUtils.IsEmptryString(response.Server)) response.Server = new RazorServerProtocolVersion().ToString(); // if there is no body, or that body is zero length we are finished if (response.Body == null) return; // if the body is zero length no problem if (response.Body.Length == 0) return; // however if there is a body with X length, we must ensure that the response's content-length header is filled in properly if (response.ContentLength != response.Body.Length) response.ContentLength = response.Body.Length; // lastly, warn if we are going to send a response with no content-type, it's just not cool if (HttpUtils.IsEmptryString(response.ContentType)) Debug.WriteLine(string.Format("The response '{0}' contains a body, but does not contain a valid 'content-type'. Please set the 'content-type' header field, or use the SetBody(XXX) methods of the HttpMessage class when setting the message body.", response.FirstLine), MY_TRACE_CATEGORY); }
/// <summary> /// Initializes a new instance of the HttpResponseEventArgs class /// </summary> /// <param name="response">The message response context</param> public HttpResponseEventArgs(HttpResponse response) : base((HttpMessage)response) { }
/// <summary> /// Determines if the request succeeded based on the status code of the response /// </summary> /// <param name="response"></param> /// <returns></returns> public static bool Succeeded(HttpResponse response) { if (response == null) return false; if (response.Status.Code == new OkStatus().Code) return true; return false; }