Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 56 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
56
Dung lượng
759,28 KB
Nội dung
4.2 HTTP 93 Chapter 4 Every HTTP response has a response code. In the above example, the response code was 200. This number is followed by some human-readable text (i.e., OK). The response codes fall into five main categories shown in Table 4.3. 4.2.3 MIME types Multipart Internet mail extensions (MIME) types are a means of describing the type of data, such that another computer will know how to handle the data and how to display it effectively to the user. To illustrate the example, if you changed the extension of a JPEG image (.JPG) to .TXT, and clicked on it, you would see a jumble of strange char- acters, not the image. This is because Windows contains a mapping from file extension to file type, and .JPG and .TXT are mapped to different file types: image/jpeg for .JPG and text/plain for .TXT. To find an MIME type for a particular file, such as .mp3, you can open the registry editor by clicking on Start > Run, then typing REGEDIT. Then click on HKEY_CLASSES_ROOT, scroll down to .mp3, and the MIME type is written next to Content Type. Note: Not all file types have a MIME type (e.g., .hlp help files). 4.2.4 System.Web One of the most common uses of HTTP within applications is the ability to download the HTML content of a page into a string. The following application demonstrates this concept. It is certainly possible to implement HTTP at the socket level, but there is a wealth of objects ready for use in HTTP client applications, and it 400–499 Redirection: Further action must be taken in order to complete the request. 500-599 Server error: The server failed to fulfill an apparently valid request. Table 4.3 HTTP response codes (continued). HTTP response code range Meaning 94 4.2 HTTP makes little sense to reinvent the wheel. The HTTP server in the next sec- tion is implemented using HTTPWebReqest. Start a new project in Visual Studio .NET, and drag on two textboxes, tbResult and tbUrl. TbResults should be set with multiline=true. A button, btnCapture, should also be added. Click on the Capture button, and enter the following code: C# private void btnCapture_Click(object sender, System.EventArgs e) { tbResult.Text = getHTTP(tbUrl.Text); } VB.NET Private Sub btnCapture_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles btnCapture.Click tbResult.Text = getHTTP(tbUrl.Text) End Sub Then implement the getHTTP function: C# public string getHTTP(string szURL) { HttpWebRequest httpRequest; HttpWebResponse httpResponse; string bodyText = ""; Stream responseStream; Byte[] RecvBytes = new Byte[Byte.MaxValue]; Int32 bytes; httpRequest = (HttpWebRequest) WebRequest.Create(szURL); httpResponse = (HttpWebResponse) httpRequest.GetResponse(); responseStream = httpResponse.GetResponseStream(); while(true) { bytes = responseStream.Read(RecvBytes, 0,RecvBytes.Length); if (bytes<=0) break; bodyText += System.Text.Encoding.UTF8.GetString(RecvBytes, 0, bytes); 4.2 HTTP 95 Chapter 4 } return bodyText; } VB.NET Public Function getHTTP(ByVal szURL As String) As String Dim httprequest As HttpWebRequest Dim httpresponse As HttpWebResponse Dim bodytext As String = "" Dim responsestream As Stream Dim bytes As Int32 Dim RecvBytes(Byte.MaxValue) As Byte httprequest = CType(WebRequest.Create(szURL), _ HttpWebRequest) httpresponse = CType(httprequest.GetResponse(), _ HttpWebResponse) responsestream = httpresponse.GetResponseStream() Do While (True) bytes = responsestream.Read(RecvBytes, 0, _ RecvBytes.Length) If bytes <= 0 Then Exit Do bodytext += System.Text.Encoding.UTF8.GetString _ (RecvBytes, 0, bytes) Loop Return bodytext End Function Taking a closer look at this code, it should be relatively easy to identify how it operates. The first action taken as this code is executed is that a static method on the WebRequest class is called and passed the string szURL as a parameter. This creates a webRequest object that can be cast to an HttpWe- bRequest object, which will handle outgoing HTTP connections. Once we have an HttpWebRequest object, we can then send the HTTP request to the server and start receiving data back from the server by calling the GetResponse method. The return value is then cast to an HttpWebResponse object, which is then held in the httPresponse variable. A response from a Web server is asynchronous by nature, so it is natural to create a stream from this returning data and read it in as it becomes avail- able. To do this, we can create a stream by calling the GetResponseStream method. Once the stream is obtained, we can read bytes from it in chunks 96 4.2 HTTP of 256 bytes (byte.Max). Reading data in chunks improves performance. The chunk size can be arbitrarily chosen, but 256 is efficient. The code sits in an infinite loop until all of the incoming data is received. In a production environment, therefore, this type of action should be contained within a separate thread. Once we have a string containing all of the HTML, we can simply dump it to screen. No other processing is required. You will also need some extra namespaces: C# using System.Net; using System.IO; VB.NET Imports System.Net Imports System.IO To test the application, run it from Visual Studio, type in a Web site address (not forgetting the http:// prefix), and press Capture. The HTML source will appear in the body (Figure 4.1). This is a very simple HTTP client, with no error handling, and is single threaded; however, it should suffice for simpler applications. Figure 4.1 HTTP client application. 4.2 HTTP 97 Chapter 4 Table 4.4 shows the significant methods of HttpWebResponse. 4.2.5 Posting data Many dynamic Web sites contain forms for login details, search criteria, or similar data. These forms are usually submitted via the POST method. This poses a problem, however, for any application that needs to query a page that lies behind such a form because you cannot specify posted data in the URL line. Table 4.4 Significant members of the HttpWebResponse class. Method or property Meaning ContentEncoding Gets the method used to encode the body of the. response. Returns String. ContentLength Gets the length of the content returned by the request. Returns Long. ContentType Gets the content type of the response. Returns String. Cookies Gets or sets the cookies associated with this request. May be used thus: Cookies[“name”].ToString(). Headers Gets the headers associated with this response from the server. May be invoked thus: Headers[“Content-Type”].ToString(). ResponseUri Gets the URI of the Internet resource that responded to the request. May be invoked thus: RequestURI.ToString(). Server Gets the name of the server that sent the response. Returns String. StatusCode Gets the status of the response. Returns the HttpStatusCode enumerated type. The StatusDescription returns a descriptive String. GetResponseHeader Gets the specified header contents that were returned with the response. Returns String. GetResponseStream Gets the stream used to read the body of the response. No asynchronous variant. Returns stream. 98 4.2 HTTP First, prepare a page that handles POST requests. In this case, type the fol- lowing lines into a file called postTest.aspx in c:\inetpub\wwwroot (your HTTP root): ASP.NET <%@ Page language="c#" Debug="true"%> <script language="C#" runat="server"> public void Page_Load(Object sender, EventArgs E) { if (Request.Form["tbPost"]!=null) { Response.Write(Request.Form["tbPost"].ToString()); } } </script> <form method="post"> <input type="text" name="tbpost"> <input type="submit"> </form> ASP.NET is a vast subject that lies outside the scope of this book; how- ever, for the sake of explaining the above example, a quick introduction is necessary. ASP.NET is an extension to IIS that enables .NET code to be executed on receipt of requests for Web pages. This also provides means for .NET code to dynamically generate responses to clients in the form of HTML, viewable on Web browsers. Incoming requests and outgoing data are mapped to objects in .NET, which can easily be read and manipulated. The most fundamental of these objects are the Request and Response objects. The Request object encapsu- lates the data sent from the Web browser to the server; of its properties, two of the most important are the Form and QueryString collections. The Form collection reads data sent from the client via the POST method, whereas the QueryString collection reads data sent from the client via the GET method. The Response object places data on the outgoing HTTP stream to be sent to the client. One of its most important methods is Write. This method is passed a string that will be rendered as HTML on the client. One of the features that makes ASP.NET more powerful than its predeces- sor, classic ASP, is its ability to model HTML elements as objects, not merely 4.2 HTTP 99 Chapter 4 as input and output streams. For example, an input box would be typically written in ASP.NET as <ASP:TEXTBOX id=”tbText” runat=”server”/>, and the properties of this textbox could then be modified from code by accessing the tbText object. In classic ASP, the only way to achieve such an effect would be to include code within the textbox declaration, such as <input type=”text” <%=someCode%>> , which is less desirable because functional code is intermixed with HTML. ASP.NET provides better performance than classic ASP because it is compiled on first access (in-line model) or precompiled (code-behind model). It also leverages the .NET framework, which is much richer than the scripting languages available to ASP. The example above is appropriate for demonstrating the posting method. Every Web scripting language handles posted data in much the same way, so the technique is applicable to interfacing with any Web form. Web scripting languages share a common feature: some sections of the page are rendered on the browser screen as HTML, and some are processed by the server and not displayed on the client. In the example, anything marked runat=”server” or prefixed <% will be processed by the server. When the user presses the submit button ( <input type=”submit”>), the browser packages any user-entered data that was contained within the <form> tags and passes it back to the server as a POST request. The server parses out the data in the POST request once it is received. The server-side script can retrieve this data by accessing the Request.Form collection. The Response.Write command prints this data back out to the browser. To try the page out, open a browser and point it at http://localhost/post- Test.aspx; type something into the textbox, and press Submit. Then you will see the page refresh, and the text you typed appears above the form. Reopen the previous example and add a new textbox named tbPost. Click on the Capture button and modify the code as follows: C# private void btnCapture_Click(object sender, System.EventArgs e) { tbPost.Text = HttpUtility.UrlEncode(tbPost.Text); tbResult.Text = getHTTP(tbUrl.Text,"tbPost="+tbPost.Text); } 100 4.2 HTTP VB.NET Private Sub btnCapture_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles btnCapture.Click tbPost.Text = HttpUtility.UrlEncode(tbPost.Text) tbResult.Text = getHTTP(tbUrl.Text,"tbPost="+tbPost.Text) End Sub The reason for the call to HttpUtility.UrlEncode is to convert the text entered by the user into a string that is safe for transport by HTTP. This means the removal of white space (spaces are converted to “+”) and the con- version of nonalphanumeric characters, which is a requirement of the HTTP protocol. Once the data to post is encoded, it can be passed to the getHTTP func- tion, which is described below. It is a modified version of the code previ- ously listed. C# public string getHTTP(string szURL,string szPost) { HttpWebRequest httprequest; HttpWebResponse httpresponse; StreamReader bodyreader; string bodytext = ""; Stream responsestream; Stream requestStream; httprequest = (HttpWebRequest) WebRequest.Create(szURL); httprequest.Method = "POST"; httprequest.ContentType = "application/x-www-form-urlencoded"; httprequest.ContentLength = szPost.Length; requestStream = httprequest.GetRequestStream(); requestStream.Write(Encoding.ASCII.GetBytes(szPost),0, szPost.Length); requestStream.Close(); httpresponse = (HttpWebResponse) httprequest.GetResponse(); responsestream = httpresponse.GetResponseStream(); bodyreader = new StreamReader(responsestream); bodytext = bodyreader.ReadToEnd(); return bodytext; } 4.2 HTTP 101 Chapter 4 VB.NET Public Function getHTTP(ByVal szURL As String, _ ByVal szPost As String) As String Dim httprequest As HttpWebRequest Dim httpresponse As HttpWebResponse Dim bodyreader As StreamReader Dim bodytext As String = "" Dim responsestream As Stream Dim requestStream As Stream httprequest = CType(WebRequest.Create(szURL), _ HttpWebRequest) httprequest.Method = "POST" httprequest.ContentType = _ "application/x-www-form-urlencoded" httprequest.ContentLength = szPost.Length requestStream = httprequest.GetRequestStream() requestStream.Write(Encoding.ASCII.GetBytes(szPost), _ 0,szPost.Length) requestStream.Close() httpresponse = CType(httprequest.GetResponse(), _ HttpWebResponse) responsestream = httpresponse.GetResponseStream() bodyreader = New StreamReader(responsestream) bodytext = bodyreader.ReadToEnd() Return bodytext End Function This differs from the code to simply retrieve a Web page in that once the HttpWebRequest has been created, several parameters are set such that the request also includes the posted data. The chunked reader loop is also replaced with the ReadToEnd() method of StreamReader. This method may be elegant, but it is not compatible with binary data. The three settings that need to be changed are the request method, con- tent type, and content length. The request method is usually GET but now must be set to POST. The content type should be set to the MIME type application/x-www-form-urlencoded, although this is not strictly neces- sary. The content length is simply the length of the data being posted, including the variable names, and after URL encoding. 102 4.2 HTTP The data to be posted must then be sent to the server using the Write method on the request stream. Once the request has been created, it is sim- ply a matter of receiving the stream from the remote server and reading to the end of the stream. Finally, we need namespaces for the HttpUtility and Encoding objects. You will need to make a reference to System.Web.dll by selecting Project →→ →→ Add Reference, as shown in Figure 4.2. C# using System.Web; using System.Text; using System.IO; using System.Net; VB.NET Imports System.Web Imports System.Text Imports System.IO Imports System.Net Figure 4.2 Visual Studio .NET, Add Reference dialog. [...]... browser window and how HTML is displayed Without the Content-Type header, Internet Explorer will mistake all XML (excluding the tag) as HTML You can see this by viewing a simple XML file containing the text through this server And, the usual namespaces are thrown in: C# using using using using using System.Threading; System.Net; System.Net.Sockets; System.Text; System.IO; VB.NET Imports... WebBrowser.Document.designMode to On Users can type directly into the Internet Explorer window and use wellknown shortcut keys to format text (e.g., Ctrl + B, Bold; Ctrl + I, Italic; Ctrl + U, Underline) By right-clicking on Internet Explorer in design mode, a user can include images, add hyperlinks, and switch to browser mode When an image is included in the design view, it can be moved and scaled by clicking... Type").ToString() End Function If you have never used Windows registry before, this code may need a little explaining The Windows registry is a repository for information that holds the vast amount of settings and preferences that keep Windows ticking over You can view and edit the registry using Registry Editor (Figure → 4.8); start this by clicking Start→Run and typing regedit or regedt32 To view... clicking and dragging on the edge of the image More advanced features can be accessed via Internet Explorer’s execCommand function Only FontName, FontSize, and ForeColor are used in the following sample program, but here is a list of the commands used by Internet Explorer Chapter 4 106 4.2 HTTP Table 4.6 Parameters of Internet Explorer’s execCommand function Command Meaning Bold Inserts a tag in HTML... manipulate graphical output, without having to be concerned with the underlying code This feature is a handy way to let users be more creative in the type of textual messages or documents they create, without requiring them to take a crash course in HTML Internet Explorer can run in a special design mode, which is acceptable as a WYSIWYG editor The trick to accessing design mode in Internet Explorer is simply... small files stored in c:\windows\cookies (depending on your Windows installation) They are placed there in one of two ways: by the JavaScript document.cookie object, or by the set-cookie header in HTTP requests These cookies remain on the client’s machine for a set time and can be retrieved in JavaScript or in HTTP responses Cookies are supported in NET via the HttpWebResponse.Cookies and the HttpWebRequest.CookieContainer... will have to determine how to display the data being sent to it C# public void handlerThread() { Socket handlerSocket = ( Socket)alSockets[alSockets.Count-1]; String streamData = ""; String filename = ""; String[] verbs; StreamReader quickRead; NetworkStream networkStream = new NetworkStream(handlerSocket); quickRead = new StreamReader(networkStream); streamData = quickRead.ReadLine(); verbs = streamData.Split("... al.AddRange(Encoding.ASCII.GetBytes(responseString)) al.AddRange(fileContents) handlerSocket.Send(CType( _ al.ToArray((New Byte).GetType()), Byte())) Finally, to support the registry access functionality, we need to include an extra namespace: Chapter 4 124 4.4 System.Net.HttpWebListener C# using Microsoft.Win32; VB.NET Imports Microsoft.Win32 To demonstrate the difference this makes to running the server,... tag in HTML Copy Copies text into the clipboard Paste Pastes text from the clipboard InsertUnorderedList Creates a bulleted list, in HTML Indent Tabulates text farther right on the page Outdent Retabulates text left on the page Italic Inserts an tag in HTML Underline Inserts an tag in HTML CreateLink Creates a hyperlink to another Web page UnLink Removes a hyperlink from text FontName Sets... (HTMLDocument)WebBrowser.Document).body.innerHTML; } VB.NET Private Sub btnViewHTML_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) tbHTML.Text= _ (CType(WebBrowser.Document, HTMLDocument)).body.innerHTML End Sub This button extracts the HTML from the Web Browser control and places it into the HTML-viewer textbox Again, the Document property must be cast to an HTMLDocument object in order . page that handles POST requests. In this case, type the fol- lowing lines into a file called postTest.aspx in c:inetpubwwwroot (your HTTP root): ASP .NET <%@ Page language=" ;c#& quot; Debug="true"%> <script. trick to accessing design mode in Internet Explorer is simply to set the property WebBrowser.Document.designMode to On. Users can type directly into the Internet Explorer window and use well- known. Italic; Ctrl + U, Underline). By right-clicking on Internet Explorer in design mode, a user can include images, add hyperlinks, and switch to browser mode. When an image is included in the design view,