Tải bản đầy đủ - 0 (trang)
10-5. Respond to HTTP Requests from Within Your Application

10-5. Respond to HTTP Requests from Within Your Application

Tải bản đầy đủ - 0trang

CHAPTER 10 ■ NETWORKING



Solution

Use the new System.Net.HttpListener class.



■ Note Your application must be running on Windows XP Service Pack 2 (or later) or Windows 2003 to use the

HttpListener class; otherwise, a System.PlatformNotSupportedException will be thrown when you try to

instantiate it. You should check the bool returned by the static property HttpListener.IsSupported to check

whether support is available.



How It Works

The HttpListener class provides an easy-to-use mechanism through which your programs can accept

and respond to HTTP requests. To use the HttpListener class, follow these steps:

1.



Instantiate an HttpListener object.



2.



Configure the URI prefixes that the HttpListener object will handle using the

Prefixes property. The Prefixes property returns a System.Net.

HttpListenerPrefixCollection collection to which you can add URI prefixes

(as strings) using the Add method. Each prefix must end with a forward slash

(/), or else a System.ArgumentException will be thrown. If you specify a URL

prefix that is already being handled, a System.Net.HttpListenerException will

be thrown. When a client makes a request, the request will be handled by the

listener configured with the prefix that most closely matches the client’s

requested URL.



3.



Start the HttpListener object by calling its Start method. You must call Start

before the HttpListener object can accept and process HTTP requests.



4.



Accept client requests using the GetContext method of the HttpListener

object. The GetContext method will block the calling thread until a request is

received and then returns a System.Net.HttpListenerContext object.

Alternatively, you can use the BeginGetContext and EndGetContext methods to

listen for requests on a thread-pool thread. When a request is received, the

System.AsyncCallback delegate specified as the argument to the

BeginGetContext method will be called and passed the HttpListenerContext

object. Regardless of how it is obtained, the HttpListenerContext object

implements three read-only properties critical to the handling of a client

request:





The Request property returns a System.Net.HttpListenerRequest through

which you can access details of the client’s request.







The Response property returns a System.Net.HttpListenerResponse through

which you can configure the response to send to the client.



493



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING







The User property returns an instance of a type implementing

System.Security.Principal.IPrincipal, which you can use to obtain

identity, authentication, and authorization information about the user

associated with the request.



5.



Configure the HTTP response through the members of the

HttpListenerResponse object accessible through the

HttpListenerContext.Response property.



6.



Send the response by calling the Close method of the HttpListenerResponse

object.



7.



Once you have finished processing HTTP requests, call Stop on the

HttpListener object to stop accepting more requests. Call Close to shut down

the HttpListener object, which will wait until all outstanding requests have

been processed, or call Abort to terminate the HttpListener object without

waiting for requests to complete.



The Code

The following example demonstrates how to use the HttpListener class to process HTTP requests. The

example starts listening for five requests concurrently using the asynchronous BeginGetContext method

and handles the response to each request by calling the RequestHandler method. Each time a request is

handled, a new call is made to BeginGetContext so that you always have the capacity to handle up to five

requests.

To open a connection to the example from your browser, enter the URL http://localhost:19080/

VisualCSharpRecipes/ or http://localhost:20000/Recipe10-05/, and you will see the response from the

appropriate request handler.

using

using

using

using

using



System;

System.IO;

System.Net;

System.Text;

System.Threading;



namespace Apress.VisualCSharpRecipes.Chapter10

{

class Recipe10_05

{

// Configure the maximum number of request that can be

// handled concurrently.

private static int maxRequestHandlers = 5;

// An integer used to assign each HTTP request handler a unique

// identifier.

private static int requestHandlerID = 0;

// The HttpListener is the class that provides all the capabilities

// to receive and process HTTP requests.

private static HttpListener listener;



494



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING



// A method to asynchronously process individual requests and send

// responses.

private static void RequestHandler(IAsyncResult result)

{

Console.WriteLine("{0}: Activated.", result.AsyncState);

try

{

// Obtain the HttpListenerContext for the new request.

HttpListenerContext context = listener.EndGetContext(result);

Console.WriteLine("{0}: Processing HTTP Request from {1} ({2}).",

result.AsyncState,

context.Request.UserHostName,

context.Request.RemoteEndPoint);

// Build the response using a StreamWriter feeding the

// Response.OutputStream.

StreamWriter sw =

new StreamWriter(context.Response.OutputStream, Encoding.UTF8);

sw.WriteLine("");

sw.WriteLine("");

sw.WriteLine("Visual C# Recipes");

sw.WriteLine("");

sw.WriteLine("");

sw.WriteLine("Recipe 10-5: " + result.AsyncState);

sw.WriteLine("");

sw.WriteLine("");

sw.Flush();

// Configure the Response.

context.Response.ContentType = "text/html";

context.Response.ContentEncoding = Encoding.UTF8;

// Close the Response to send it to the client.

context.Response.Close();

Console.WriteLine("{0}: Sent HTTP response.", result.AsyncState);

}

catch (ObjectDisposedException)

{

Console.WriteLine("{0}: HttpListener disposed--shutting down.",

result.AsyncState);

}

finally

{



495



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING



// Start another handler if unless the HttpListener is closing.

if (listener.IsListening)

{

Console.WriteLine("{0}: Creating new request handler.",

result.AsyncState);

listener.BeginGetContext(RequestHandler, "RequestHandler_" +

Interlocked.Increment(ref requestHandlerID));

}

}

}

public static void Main(string[] args)

{

// Quit gracefully if this feature is not supported.

if (!HttpListener.IsSupported)

{

Console.WriteLine(

"You must be running this example on Windows XP SP2, ",

"Windows Server 2003, or higher to create ",

"an HttpListener.");

return;

}

// Create the HttpListener.

using (listener = new HttpListener())

{

// Configure the URI prefixes that will map to the HttpListener.

listener.Prefixes.Add(

"http://localhost:19080/VisualCSharpRecipes/");

listener.Prefixes.Add(

"http://localhost:20000/Recipe10-05/");

// Start the HttpListener before listening for incoming requests.

Console.WriteLine("Starting HTTP Server");

listener.Start();

Console.WriteLine("HTTP Server started");

Console.WriteLine(Environment.NewLine);

// Create a number of asynchronous request handlers up to

// the configurable maximum. Give each a unique identifier.

for (int count = 0; count < maxRequestHandlers; count++)

{

listener.BeginGetContext(RequestHandler, "RequestHandler_" +

Interlocked.Increment(ref requestHandlerID));

}

// Wait for the user to stop the HttpListener.

Console.WriteLine("Press Enter to stop the HTTP Server");

Console.ReadLine();



496



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING



// Stop accepting new requests.

listener.Stop();

// Terminate the HttpListener without processing current requests.

listener.Abort();

}

// Wait to continue.

Console.WriteLine(Environment.NewLine);

Console.WriteLine("Main method complete. Press Enter");

Console.ReadLine();

}

}

}



10-6. Get an HTML Page from a Site That Requires

Authentication

Problem

You need to retrieve a file from a web site, but the web site requires that you provide credentials for the

purpose of authentication.



Solution

Use the System.Net.WebRequest and System.Net.WebResponse classes as described in recipe 10-4. Before

making the request, configure the WebRequest.Credentials and WebRequest.Certificates properties

with the necessary authentication information.



■ Tip You could also use the System.Net.WebClient class (discussed in recipe 10-3), which also has

Credentials and Certificates properties that allow you to associate user credentials with a web request.



How It Works

Some web sites require user authentication information. When connecting through a browser, this

information might be submitted transparently (for example, on a local intranet site that uses Windows

integrated authentication), or the browser might request this information with a login dialog box. When

accessing a web page programmatically, your code needs to submit this information. The approach you

use depends on the type of authentication implemented by the web site:



497



www.it-ebooks.info



CHAPTER 10 ■ NETWORKING







If the web site is using basic or digest authentication, you can transmit a username

and password combination by manually creating a new System.Net.

NetworkCredential object and assigning it to the WebRequest.Credentials

property. With digest authentication, you may also supply a domain name.







If the web site is using Windows integrated authentication, you can take the same

approach and manually create a new System.Net.NetworkCredential object.

Alternatively, you can retrieve the current user login information from the

System.Net.CredentialCache object using the DefaultCredentials property.







If the web site requires a client certificate, you can load the certificate from a file

using the System.Security.Cryptography.X509Certificates.X509Certificate2

class and add that to the HttpWebRequest.ClientCertificates collection.







You can load an X.509 certificate from a certificate store using the class

System.Security.Cryptography.X509Certificates.X509Store defined in the

System.Security.dll assembly. You can either find a certificate in the store

programmatically using the X509Store.Certificates.Find method or present the

user with a Windows dialog box and allow them to select the certificate. To

present a dialog box, pass a collection of X.509 certificates contained in an

X509Certificate2Collection object to the SelectFromCollection method of the

System.Security.Cryptography.X509Certificates.X509Certificate2UI class.



The Code

The following example demonstrates all four of the basic approaches described previously. Note that

you need to add a reference to the System.Security.dll assembly.

using System;

using System.Net;

using System.Security.Cryptography.X509Certificates;

namespace Apress.VisualCSharpRecipes.Chapter10

{

class Recipe10_06

{

public static void Main()

{

// Create a WebRequest that authenticates the user with a

// username and password combination over basic authentication.

WebRequest requestA = WebRequest.Create("http://www.somesite.com");

requestA.Credentials = new NetworkCredential("userName", "password");

requestA.PreAuthenticate = true;

// Create a WebRequest that authenticates the current user

// with Windows integrated authentication.

WebRequest requestB = WebRequest.Create("http://www.somesite.com");

requestB.Credentials = CredentialCache.DefaultCredentials;

requestB.PreAuthenticate = true;



498



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

10-5. Respond to HTTP Requests from Within Your Application

Tải bản đầy đủ ngay(0 tr)

×