How does a Body get applied to an HTTP request? - asp.net

In a previous post (link below) I was able to figure out how to apply a body to an HTTP request using VB.NET and the HttpWebRequest class object. However, I'm trying to understand how this is working technically. In other words:
How is the body actually being added to the http request because I don't see it being assigned to a property of the request object?
Here's the code snippet.
Dim vHTTPREQUESTBODY As String = "the body of the request"
Dim vBYTEVERSIONOFBODY As Byte() = Encoding.ASCII.GetBytes(vHTTPREQUESTBODY)
vHTTPREQUEST.ContentLength = vBYTEVERSIONOFBODY.Length
Dim vDATASTREAM As Stream = vHTTPREQUEST.GetRequestStream()
vDATASTREAM.Write(vBYTEVERSIONOFBODY, 0, vBYTEVERSIONOFBODY.Length)
vDATASTREAM.Close()
Any help appreciated and more information below for those interested.
More Information
Why the question:
What is confusing to me is that you cannot clearly see where/how the body is added to the request before it is sent. As in older VB objects doing the same, there would be simple “Body” property for that object to set a value to. For example, in line 3 of the above, you can see the “vHTTPREQUEST.ContentLength” property set. However, you don’t see something like that for the body as in “vHTTPREQUEST.BodyOrBlahBlahBlah”. Yet, somehow the above does add the body string you set in the “vHTTPREQUESTBODY” variable to the request.
Can anyone explain how? I've search online and nothing specifically addresses this.
This is my guess:
Take a look at line 5. If you look up the “Write” method of the “Stream” object it basically states what is happening is that you are adding the bytes you placed in the first parameter of that method to the end of the current stream. So... I’m assuming what is happening is that the stream is in the computer’s memory at that point of the code, and when you use the “Write” method you are adding your body in the form of bytes to that stream that is already in memory. Therefore, you don’t need to explicitly assign it to a request of the property. Again that is a guess. I was hoping for confirmation or the true explanation or a resource/reference where I can read about this.
Previous Post:
Here's a link to previous post

Related

Sending POST with groovy and data is already URL-encoded

I'm trying to send a POST using Groovy HTTPBuilder but the data I want to send is already URL-encoded so I want HTTPBuilder to POST it as is. I tried the following:
def validationString = "cmd=_notify-validate&" + postData
def http = new HTTPBuilder(grailsApplication.config.grails.paypal.server)
http.request(Method.POST) {
uri.path = "/"
body = validationString
requestContentType = ContentType.TEXT
response.success = { response ->
println response.statusLine
}
}
But it gives me a NullPointerException:
java.lang.NullPointerException
at groovyx.net.http.HTTPBuilder$RequestConfigDelegate.setBody(HTTPBuilder.java:1200)
Since you're using pre-encoded form values you cannot use the default map-based content type encoder. You must specify the content type so the EncoderRegistry knows how to handle the body.
You may create the HttpBuilder with a content type that specifies the body is a URL-encoded string:
def http = new HTTPBuilder(url, ContentType.URLENC)
Or make the request passing the content type explicitly:
http.request(Method.POST, ContentType.URLENC) {
// etc.
For reference, here's how I figured it out--I didn't know before I read the question.
Looked at the request method's API docs to see what the closure was expected to contain. I've used HTTPBuilder only in passing, so I wanted to see what, specifically, the body "should" be, or "may" be, and if the two were different.
The four-arg version of the request method links to the RequestConfigDelegate class and said the options were discussed in its docs.
The RequestConfigDelegate.setBody method, which is what the body setter is, states the body "[...] may be of any type supported by the associated request encoder. That is, the value of body will be interpreted by the encoder associated with the current request content-type."
The request encoder link is to the EncoderRegistry class. It has an encode_form method taking a string and states it "assumes the String is an already-encoded POST string". Sounds good.
The request content-type link was to an HttpBuilder inner class method, RequestConfigDelegate.getRequestContentType, which in turn had a link to the ContentType enum.
That enum has a URLENC value that led me to believe it'd be the best first guess.
I tried the HTTPBuilder ctor taking a content type, and that worked.
Circled back to the request methods and noticed there's a version also taking a content type.
I'd guess the total time was ~5-10 minutes, much shorter than it took to type up what I did. Hopefully it'll convince you, though, that finding this kind of stuff out is possible via the docs, in relatively short order.
IMO this is a critical skill for developers to groom, and make you look like a hero. And it can be fun.

asp.net response dual content type

i am sending a large amount of excel content data to the browser using Page.Response.Write("") in a for loop.
before starting the loop i am changing the conetnt type of the reponse.context property to "ms-excel".
if i have an exception during that for loop , i try to popup an error message to the browser by registering an HTML startup script block and Write it to the browser. before the write i change back the content type to be text/html.
but i get an error that say that is not possible to change the content type after sending the HTTP Headers.
How to notify the browser about an error that occured during that for loop?
Is it possible to have more that one respone to the same browser tab?
by the way,right now i don't want to use ASP.NET AJAX.
Did you try Response.ClearHeaders(); before changing the context type?
If that doesn't work because your Response.Write is causing problems, you might think about going the route of building a string before deciding your content type and then setting the headers.
Loop trough the content and add to a StringBuilder
If no error, set contenttype to ms-excel and write out SB
If there is an error, leave contenttype as it is write out your error message as needed.
Page.Response.Write("") will send data to the browser. When you do that the browser needs to know the type of content it gets in order to render it correct. If you already told the browser what kind of content you have(and even if you don't, you are already sening data with Response.Write, it will use the default value which I think is text/html) then you can't take it back. Whatever you are saying to the client is said and you can't take it back.
The way to solve your problem is to cache the reply as suggested by Doozer.
/Tibi

Is it considered bad practice to perform HTTP POST without entity body?

I need to invoke a process which doesn't require any input from the user, just a trigger. I plan to use POST /uri without a body to trigger the process. I want to know if this is considered bad from both HTTP and REST perspectives?
I asked this question on the IETF HTTP working group a few months ago. The short answer is: NO, it's not a bad practice (but I suggest reading the thread for more details).
Using a POST instead of a GET is perfectly reasonable, since it also instructs the server (and gateways along the way) not to return a cached response.
POST is completely OK. In difference of GET with POST you are changing the state of the system (most likely your trigger is "doing" something and changing data).
I used POST already without payload and it "feels" OK. One thing you should do when using POST without payload: Pass header Content-Length: 0. I remember problems with some proxies when I api-client didn't pass it.
If you use POST /uri without a body it is something like using a function which does not take an argument .e.g int post (void); so it is reasonable to have function to your resource class which can change the state of an object without having an argument. If you consider to implement the Unix touch function for a URI, is not it be good choice?
Yes, it's OK to send a POST request without a body and instead use query string parameters. But be careful if your parameters contain characters that are not HTTP valid you will have to encode them.
For example if you need to POST 'hello world' to and end point you would have to make it look like this: http://api.com?param=hello%20world
Support for the answers that POST is OK in this case is that in Python's case, the OpenAPI framework "FastAPI" generates a Swagger GUI (see image) that doesn't contain a Body section when a method (see example below) doesn't have a parameter to accept a body.
the method "post_disable_db" just accepts a path parameter "db_name" and doesn't have a 2nd parameter which would imply a mandatory body.
#router.post('/{db_name}/disable',
status_code=HTTP_200_OK,
response_model=ResponseSuccess,
summary='',
description=''
)
async def post_disable_db(db_name: str):
try:
response: ResponseSuccess = Handlers.databases_handler.post_change_db_enabled_state(db_name, False)
except HTTPException as e:
raise (e)
except Exception as e:
logger.exception(f'Changing state of DB to enabled=False failed due to: {e.__repr__()}')
raise HTTPException(HTTP_500_INTERNAL_SERVER_ERROR, detail=e.__repr__())
return response

Checking The Date A Webpage Has Been Updated?

I want to be able to run a little script that I can populate with a list of URLs and it pulls in and checks when the page was last updated? Has anyone done this?
I can only find a manual way of doing this using JavaScript by pasting this into the browser URL field
javascript:alert(document.lastModified)
Any ideas greatly received :)
The following will step through an array of URLs and display the last modified date or, if it's not present, the date of the server request.
string[] urls = { "http://boflynn.net", "http://slashdot.org" };
foreach ( string url in urls )
{
System.Net.HttpWebRequest req =
(System.Net.HttpWebRequest) System.Net.WebRequest.Create(url);
System.Net.HttpWebResponse resp =
(System.Net.HttpWebResponse) req.GetResponse();
Console.WriteLine("{0} - {1}", url, resp.LastModified);
}
If you use urllib2 (or perhaps httplib might be better still) in a python script you can inspect the headers that are returned for the last-modified field.
It depends on what you mean by "last updated". Sure, there is the Last-Modified HTTP header, but it can be very misleading. For example, if the page is being served up dynamically, there is a good change that this field will be the current time, even if the content of the page itself (the part useful to humans) has not been updated in a rather long time. This page itself is a good example of this phenomenon.
If you are truly interested in the last time the content was updated, then I don't have an immediate answer.

how to get the content of a value posted as the body in asp classic?

I've seen a couple of rest examples where the xml message gets posted in the body of the http request, and not in a named parameter...
in classic asp I have the request.form object that allows me to get the posted values, but I have to specify the name of the parameter...
is there some way to get the whole content of the post?
I would need the equivalent of
request.serverVariables("QUERY_STRING"), but for the post, not the get part of the http request...
( http://www.w3schools.com/ASP/coll_servervariables.asp )
would I have to use request.binaryRead()???
thanks a lot
ps: in java, I cold achieve this using request.getReader()...
how to get a the value of an http post as a whole? parsing restful post
--
just to clarify thing a little bit
when I say post a value as the body, I mean that the content of the message is not enconded like param1=value1&param2=value2...paramx=valuex
the message is the body itself... you can achieve this with any ajax library (like prototype) to test ir I'm using a firefox plugin that let you do that, it's named POSTER
https://addons.mozilla.org/en-US/firefox/addon/2691
A developer tool for interacting with web services and other web resources that lets you make HTTP requests, set the entity body, and content type. This allows you to interact with web services and inspect the results...
You didn't specify either what actual content type is being posted nor what you intented to do with it once you've acquired it.
Lets assume for a moment that the content is XML and you want to load it into an XML DOM.
A useful fact about the Request object is that it implements IStream where the stream is the entity body of the POST. Another useful fact is MSXML DOMDocument load method can accept an implementation of IStream. Hence:-
Dim xml: Set xml = CreateObject("MSXML2.DOCDocument.3.0")
xml.async = false
xml.load Request
This code loads the posted entity body into the DOM.
I think I found it
if you issue str( request.form ) you get the raw value of the form element...
works also with request.querystring and request.cookies
it doesn't work with request.serverVariables, throws an exception...
oh, and inspecting the debugger I've also found a completely undocumented property, request.body, that seems to behave just like the request.form property...
Are you trying to loop through all the posted values from the form? If so in ASP.OLD you could do this:
For Each Field in Request.Form

Resources