Process raw HTTP request content - asp.net

I am doing an e-commerce solution in ASP.NET which uses PayPal's Website Payments Standard service. Together with that I use a service they offer (Payment Data Transfer) that sends you back order information after a user has completed a payment. The final thing I need to do is to parse the POST request from them and persist the info in it. The HTTP request's content is in this form :
SUCCESS
first_name=Jane+Doe
last_name=Smith
payment_status=Completed
payer_email=janedoesmith%40hotmail.com
payment_gross=3.99
mc_currency=USD
custom=For+the+purchase+of+the+rare+book+Green+Eggs+%26+Ham
Basically I want to parse this information and do something meaningful, like send it through e-mail or save it in DB. My question is what is the right approach to do parsing raw HTTP data in ASP.NET, not how the parsing itself is done.

Something like this placed in your onload event.
if (Request.RequestType == "POST")
{
using (StreamReader sr = new StreamReader(Request.InputStream))
{
if (sr.ReadLine() == "SUCCESS")
{
/* Do your parsing here */
}
}
}
Mind you that they might want some special sort of response to (ie; not your full webpage), so you might do something like this after you're done parsing.
Response.Clear();
Response.ContentType = "text/plain";
Response.Write("Thanks!");
Response.End();
Update: this should be done in a Generic Handler (.ashx) file in order to avoid a great deal of overhead from the page model. Check out this article for more information about .ashx files

Use an IHttpHandler and avoid the Page model overhead (which you don't need), but use Request.Form to get the values so you don't have to parse name value pairs yourself. Just pretend you're in PHP or Classic ASP (or ASP.NET MVC, for that matter). ;)

I'd strongly recommend saving each request to some file.
This way, you can always go back to the actual contents of it later. You can thank me later, when you find that hostile-endian, koi-8 encoded, [...], whatever it was that stumped your parser...

Well if the incoming data is in a standard form encoded POST format, then using the Request.Form array will give you all the data in a nice to handle manner.
If not then I can't see any way other than using Request.InputStream.

If I'm reading your question right, I think you're looking for the InputStream property on the Request object. Keep in mind that this is a firehose stream, so you can't reset it.

Related

Send a File as well as parameters (through JSON) inside one HTTP request

I am creating a server using Go that allows the client to upload a file and then use a server function to parse the file. Currently, I am using two separate requests:
1) First request sends the file the user has uploaded
2) Second request sends the parameters to the server that the server needs to parse the file.
However, I have realised that due to the nature of the program, there can be concurrency problem if multiple users try to use the server at the same time. My solution to that was using mutex locks. However, I am receiving the file, sending a response, and then receiving the parameters and it seems that Go cannot send a response back when the mutex is locked. I am thinking about solving this problem by sending both the file and the parameters in one single HTTP request. Is there a way to do that? Thanks
Sample code (only relevant parts):
Code to send file from client:
handleUpload() {
const data = new FormData()
for(var x = 0; x < this.state.selectedFile.length; x++) {
data.append('myFile', this.state.selectedFile[x])
}
var self = this;
let url = *the appropriate url*
axios.post(url, data, {})
.then(res => {
//other logic
self.handleParser();
})
}
Code for handleParser():
handleNessusParser(){
let parserParameter = {
SourcePath : location,
ProjectName : this.state.projectName
}
// fetch the the response from the server
let self = this;
let url = *url*
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(parserParameter),
}).then( (response) => {
if(response.status === 200) {
//success logic
}
}).catch (function (error) {
console.log("error: ", error);
});
}
The question is not really about Go or reactjs or any particular software library.
To solve your problem you'd first need to understand how HTTP POST works,
hence I invite you to first read this intro on MDN.
In short:
There are multiple ways to encode the data sent in a POST request.
The way the receiver should deal with this data depends on how it's encoded by the sender.
The sender has to communicate the encoding with its request — usually via the Content-Type header field.
I won't go into the details of possible encodings — the referenced introductory material covers them, and you should do your own research on them, but to maybe recap what's written there, here is some perspective.
Back in the 80s and 90s the web was "static" and the dreaded era of JavaScript-heavy "web apps" did not yet come. "Static" means you could not run any code in the client's browser, and had to encode any communication with the server in terms of plain HTML.
An HTML document could have two ways to make the client rendering it to send something back to the server: a) embed an URL which would include query parameters; this would make the client to perform a GET request with these parameters sent to the server; b) embed an HTML "form" which, when "submitted", would result in performing a rather more complex POST request with the data taken from the filled in form.
The latter approach was the way to leverage the browser's ability to perform reasonably complex data processing — such as slurpling a file selected by the user in a specific form's control, encoding it appropriately and sending it to the server along with the other form's data.
There were two ways to encode the form's data, and they are both covered by the linked article, please read about them.
The crucial thing to understand about this "static web with forms" approach is that it worked like this: the server sends an HTML document containing a web form, the browser renders the document, the user fills the form in and clicks the "submit" button rendered by the browser; the browser collects the data from the form's controls, for entries of type "file" it reads and encodes the contents of those files and finally performs an HTTP POST request with this stuff encoded to the URL specified by the form. The server would typically respond with another HTML document and so on.
OK, so here came "web 2.0", and an "XHR" (XMLHttpRequest) was invented. It has "XML" in its name because that was the time when XML was perceived by some as a holy grail which would solve any computing problem (which it, of course, failed to do). That thing was invended to be able to send almost arbitrary data payloads; XML and JSON encoding were supported at least.
The crucial thing to understand is that this way to communicate with the server is completely parallel to the original one, and the only thing they share is that they both use HTTP POST requests.
By now you should possibly see the whole picture: contemporary JS libs allow you to contruct and perform any sort of request: they allow you to create a "web form"-style request or to create a JS object, and serialise it to JSON, and send the result in an HTTP POST request.
As you can see, any approach allows you to pass structured data containing multiple distinct pieces of data to the server, and the way to handle this all is a matter of agreement between the server and the client, that is, the API convention, if you want.
The difference between various approaches is that the web-form-style approach would take care of encoding the contents of the file for you, while if you opt to send your file in a JSON object, you'll need to encode it yourself — say, using base64 encoding.
Combined approaches are possible, too.
For instance, you can directly send binary data of a file as a POST request's body, and submit a set of parameters along with the request by encoding them as query-parameters of the URL. Again, it's up to the agreement between the client and the server about how the latter encodes the data to be sent and the former decodes them.
All-in-all, I'd recommend to take a pause and educate yourself on the stuff I have outlined above, and then have another stab at solving the problem, but this time — with reasonably complete understanding about how the stuff works under the hood, and how you intend to wield it.

In ASP.NET, how do I modify POST data and then redirect/POST it to another URL?

I have a page that's sending some POST data in plaintext to an aspx page I wrote:
firstname: John
lastname: Doe
accountid: 123
I need to take this POST data and run it through an encrypting algorithm so the data ends up like so:
firstname: AKFJULKHI
lastname: IDKLNZUI
accountid: RIQLKKNIC
After encoding it, I then need to POST it to another aspx page that's expecting this encoded data. I cannot modify this page. Essentially, I'm writing an in-between page whose purpose is to take some plaintext data, encode it using a proprietary algorithm, and pass it to another page that expects this encrypted data. I realize it's a useless security feature because the user knows what the data is before the encryption, but I cannot modify the other pages and have to stick to the API.
My question is, what is the easiest way of doing this? Response.Redirect will convert it to a GET request, and Server.Transfer will not change the URL on the client side. I could do a manual POST request and then do a Response.Write, but that seems like a really roundabout way of doing it.
I think you may want to approach this with a module instead. The HttpModule intercepts the request, can change the request and then the request continues on to the target and the target page is unaware that the request was modified.,
ref: http://www.codeproject.com/Articles/30907/The-Two-Interceptors-HttpModule-and-HttpHandlers#HttpModuletheeventbasedpreprocessor
HTTP does not support POST redirects.
Instead, you can render a simple page with an HTML form containing hidden inputs with your modified data and pointing to the new URL, then automatically submit the form using Javascript.

Retrieving HTML from ASP.NET page on postback

I've found a few posts about retrieving HTML from an ASPX page, mostly by overriding the render method, using a WebClient, or creating an HttpWebRequest. All these methods return the HTML of the page as it's loaded, but I was hoping to actually retrieve the HTML after the user has entered information.
The purpose behind this is that I work in IT, and I'm attempting to build a logging library that has an overload that essentially does a "screen-scrape" on the page just as the user encounters an exception, that way I can log the exception, and create an HTML file in a sub-directory of the logging directory that shows the page exactly as the user had it before clicking "submit" or having some other random error, and add an "ID" to the error that's logged telling whoever is fixing the issue which page to look at.
I hope I've provided enough information, because I really have no idea where to start.
Also, We'd like to do this through our own library, because our logging library is included in our common library, and many of our common library functions use our logging class.
Hmmm...
If you want to see what the user sees after they've been using the page, you're most likely going to have to do some fancy client-side scripting.
A naive approach:
When the clicks the submit button, fire a JavaScript event that encodes the DOM and either passes it as a form variable to the server, or executes a separate AJAX request with the encoded data as a parameter. ("Encode" in this case may be as simple as grabbing document.innerHtml, but I haven't checked.)
This potentially introduces a lot of overhead to every form submission, so I'd keep it out of production code.
I'm not sure why you need the rendered HTML as part of your exception log - I've never found it necessary for server-side debugging.
You getting HTML code from a website. You can use code like this.
string urlAddress = "http://www.jobdoor.in";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlAddress);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = null;
if (response.CharacterSet == null)
readStream = new StreamReader(receiveStream);
else
readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
string data = readStream.ReadToEnd();
response.Close();
readStream.Close();
}

ASP.NET's equivalent of PHP's $_GET and $_POST?

As thet title says.
I'm new to asp.net, and I'm sorta trying to build some AJAX-stuff to learn.
ASP.Net AJAX may also be worth reading as there are some built-in things that could be useful.
"Request.QueryString" and "Request.Form" are the likely answers to the title question.
Following up with marr75's response, the Request property exposes a dictionary of GETed and POSTed variables.
See http://msdn.microsoft.com/en-us/library/swe97x0b.aspx.
It explains how to access the response and request context. If you're going to do ajax stuff, you might want to think about WCF REST, in which case, it's totally different and I would recommend going through some tutorials to see how the http elements of the application are abstracted away. In any event, in a lot of ASP.NET development, you don't touch the response and request contexts directly.
Request object is a map of all the request headers - both from the POST request and URL encoded params:
//This will retrieve the value of "SomeHeader" from the request
//e.g. http://localhost/page.aspx?SomeHeader=thisisvalue
string value = HttpContext.Current.Request["SomeHeader"];
//value == "thisisvalue"

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