// Request processing method...
        public void ProcessRequest(HttpContext context)
        {
            string uri = context.Request.RawUrl.ToLower();;

            Init(uri);

            Trace.WriteLine(string.Format("HttpReceiveAdapter.ProcessRequest( uri:{0} ) called", uri), "HttpReceive: Info");

            HttpReceiveEndpoint ep = base.GetEndpoint(uri) as HttpReceiveEndpoint;

            if (null == ep)
            {
                throw new ApplicationException("BizTalk HTTP receive adapter failed to initialize itself. Possible reasons:\n" +
                                               "1) Receive location URL is not created/configured correctly\n" +
                                               "2) Receive location is not enabled\n" +
                                               "3) HTTP receive adapter is not running under a user that has access to management and message databases\n" +
                                               "4) Isolated host instance is not created for HTTP Receive adapter.\n");
            }

            // Determine if the port is one or two and handle accordingly...
            if (ep.Configuration.PortIsTwoWay)
            {
                ProcessRequestResponse(uri, context, ep);
            }
            else
            {
                ProcessRequest(uri, context, ep);
            }
        }
        IBaseMessage ConstructMessage(string uri, HttpContext context, HttpReceiveEndpoint ep)
        {
            // Create a new message...
            IBaseMessage     msg  = this.msgFactory.CreateMessage();
            IBaseMessagePart body = this.msgFactory.CreateMessagePart();

            msg.AddPart("Body", body, true);

            // Attach the request stream to the message body part...
            Stream stream = context.Request.InputStream;

            if (!stream.CanSeek)
            {
                // The stream must be seekable for property error handling!
                stream = new VirtualStream(stream);
            }
            msg.BodyPart.Data = stream;

            // Determine the charset and content type and stamp on the message context...
            body.ContentType = context.Request.ContentType;
            body.Charset     = context.Request.ContentEncoding.WebName;

            // If we have a Windows User, stamp it on the msg ctx...
            string user = context.User.Identity.Name;

            if (user.Length > 0)
            {
                msg.Context.Write(WindowsUserProperty.Name.Name, WindowsUserProperty.Name.Namespace, user);
            }

            // Note: this sample does not handle certificates. If it did it would
            // stamp the Cert Thumb Print ont he message context property: SignatureCertificate

            // Promote the InboundTransportLocation and InboundTransportType
            msg.Context.Promote(InboundTransportLocationProperty.Name.Name, InboundTransportLocationProperty.Name.Namespace, uri);
            msg.Context.Promote(InboundTransportTypeProperty.Name.Name, InboundTransportTypeProperty.Name.Namespace, protocol);

            // If Loopback is configured, stamp it on the message context...
            if (ep.Configuration.LoopBack && ep.Configuration.PortIsTwoWay)
            {
                msg.Context.Write(LoopBackProperty.Name.Name, LoopBackProperty.Name.Namespace, true);
            }

            return(msg);
        }
        private void ProcessRequest(string uri, HttpContext context, HttpReceiveEndpoint ep)
        {
            // Create a new message...
            IBaseMessage msg = ConstructMessage(uri, context, ep);

            // Submit the message using the StandardReceiveBatchHandler
            SyncReceiveSubmitBatch batch = new SyncReceiveSubmitBatch(transportProxy, terminator, 1);

            // Do one-way-submit
            batch.SubmitMessage(msg, null);
            batch.Done();

            if (!batch.Wait())
            {
                Trace.WriteLine("HttpReceiveAdapter.ProcessRequest(): Failed to process the Http Request!", "HttpReceive: Error");
                throw new HttpException(400, "Failed to process the Http Request");
            }

            context.Response.StatusCode = 202;
        }
        private void ProcessRequestResponse(string uri, HttpContext context, HttpReceiveEndpoint ep)
        {
            // Create a new message...
            IBaseMessage msg = ConstructMessage(uri, context, ep);

            // Use the request-response handler to send the request message
            SyncReceiveSubmitBatch batch = new SyncReceiveSubmitBatch(this.transportProxy, terminator, 1);

            DateTime            expDateTime     = DateTime.Now.AddSeconds(ep.Configuration.Timeout);
            HttpResponseHandler responseHandler = new HttpResponseHandler(this.transportProxy);

            // Do two-way submit operation: EPM should generate a response in this case
            batch.SubmitRequestMessage(msg, Guid.NewGuid().ToString("D"), true, expDateTime, responseHandler);

            // Done will call "Enter" on the terminator to ensure proper ref-counting
            batch.Done();

            // Wait for the callback (this should always complete quickly)
            if (!batch.Wait())
            {
                throw new HttpException(500, "Failed to submit the Http request to BizTalk Server");
            }

            if (batch.FailedMessages.Count != 0)
            {
                throw new HttpException(500, "Failed to submit the Http request to BizTalk Server");
            }

            // It's a good idea to have a timeout on the response message
            IBaseMessage responseMsg = responseHandler.WaitForResponse(ep.Configuration.Timeout);

            if (responseMsg == null)
            {
                // Response did not arrive in time!
                throw new HttpException(500, "Failed to retrieve the Http response message from BizTalk Server");
            }

            // Copy the data from the response message into the HTTP response stream.
            Exception transmitException = null;

            try
            {
                using (Stream httpStream = context.Response.OutputStream)
                {
                    // Set the response content-type (ideally, this should be extracted from message)
                    context.Response.ContentType = ep.Configuration.ReturnContentType;

                    Stream btsStream = responseMsg.BodyPart.GetOriginalDataStream();

                    // Note, the data is handled in a streaming fashion to
                    // prevent us going out of memory for large messages.
                    int    bytesRead = 0;
                    byte[] buff      = new byte[IO_BUFFER_SIZE];
                    while ((bytesRead = btsStream.Read(buff, 0, IO_BUFFER_SIZE)) > 0)
                    {
                        httpStream.Write(buff, 0, bytesRead);
                    }

                    httpStream.Flush();
                }
            }
            catch (Exception ex)
            {
                transmitException = ex;
            }
            finally
            {
                // After processing the response message successfully, it MUST be deleted
                // from BizTalk message box (a.k.a. Application Queue). Otherwise, the message
                // remain in the queue forever causing the system to become unresponsive.
                responseHandler.ResponseConsumed(transmitException);
            }
        }