Delphi synapse TTCPBlockSocket - http

EDIT: I need to make a POST connection with TTCPBlocksocket inside a delphi based applications script engine.
How to tell synapse where Header ends and body (post elements) starts? Or should i send them in different packets? Thank you !
begin
Head:= TStringList.Create;
Head.Add('GET / HTTP/1.1');
Head.Add('Accept: */*');
Head.Add('Accept-Encoding: gzip, deflate');
Head.Add('Host: www.google.ru');
Head.Add('Connection: Keep-Alive');
Head.Add(#10#13);
body:= TStringList.Create;
body.Add('username=adr');
body.Add('login=adr');
body.Add('password=adr');
body.Add('r_password=adr');
body.Add('submit=register');
Socket:= TTCPBlockSocket.Create;
Socket.connect('108.167.137.28', '80');
if (Socket.LastError <> 0) then Exit;
Socket.SendString(Head.Text);

Solved by this topic -
How are parameters sent in an HTTP POST request?
The content is put after the HTTP headers. The format of an HTTP POST
is to have the HTTP headers, followed by a blank line, followed by the
request body. The POST variables are stored as key-value pairs in the
body.

Related

how to send a multi-part POST with curl without knowing total size of input

I am working on a project which involves sending voice over http stream, i am currently using CURL for my Http backend. I see that if i need to use "Transfer-Encoding: chunked" i need to mention the total stream size/"Content-length:" . I am currently waiting for the stream to complete from which i will know the total content size . which works but is causing significant delay . i would like to know how can i upload the data in chunks without knowing the total content length of the input.
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "audio",
CURLFORM_CONTENTTYPE, MULTI_PART_CONTENT_TYPE_AUDIO,
CURLFORM_STREAM, &(*(aBufffer)),
CURLFORM_CONTENTSLENGTH,bufferSize,
CURLFORM_END);
the documentation for "CURLFORM_STREAM" specifies that it is mandatory to specify "CURLFORM_CONTENTSLENGTH" . I need to use "CURLFORM_STREAM" because my buffer is big and I want curl to call "CURLOPT_READFUNCTION" to post the remaining data.
looking at the http request header specification for content-length and about the message body indicate that this header could be optional for POST request as long as the Transfer-Encoding header is specified.
The server would look for a message body if either one of the header is present.
The problem is that you would have to find a way to figure out on the server if the message have been fully received.
Tell libcurl to do the POST using chunked encoding by setting the header. See example below. You can then simply lie and set CURLFORM_CONTENTSLENGTH to some non-zero value since libcurl won't pass on a Content-Length: in its request anyway.
struct curl_slist *headerlist =
curl_slist_append(NULL, "Transfer-Encoding: chunked");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
/* pass in the created formpost data */
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
/* send the entire thing away */
curl_easy_perform(curl);

Why "Invalid Content Type"

Trying to update a data field on a lead record in Marketo. Using C#. I send:
{"action":"updateOnly","input":[{"email":"dfranks#gmail.com","leadQuality":"Hot"}]}
And get back:
{"requestId":"d98e#14b2d7dd1f3","success":false,"errors":[{"code":"612","message":"Invalid Content Type"}]}
Why the Invalid Content type message? The field leadQuality is legit. The email address exists. I've tried a number of different fields and always the same message. Access token is good too.
Content-Type is a HTTP header. Usually, you set it to application/json for REST calls.
You should do this in the code where you generate the HTTP request or REST call.
I found text/json as Content-Type and Accept header value in one of the marketo examples. You might try one of the two choices.
Here are a couple of things to check:
As #StephenKing mentioned, I would check that your Content-Type HTTP
Header is set to "application/json".
I would also confirm that the custom field you created for "leadQuality"
has a String data type.

Why are POST params put in the request body, instead of in the URL like GET?

Why are POST params put in the request body, instead of in the URL like GET?
I understand that GET requests are meant to read data, while POST requests are meant to alter data (i.e. if a POST request is sent more than once, dicey things can happen). But why the difference in URL vs body? Putting the text in the body doesn't seem significantly more secure or private.
It's not about security or privacy, but about data.
You can send anything you want in the body, while the URI (specifically the query string) is quite restrictive in content and length.
The HTTP request has two parts: The header and the body
The header contains all information which describes the request and the requested object (path, request parameters, options, etc) and the requested operation (GET, POST, PUT, DELETE, etc).
The body contains all data which are sent by the client to process. This data could be some kind of binary data (an image for example), or some kind of form data (POST data).
This is the HTTP request specification: http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
Here are the definitions of the HTTP request methods:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Are PUT and POST requests required/expected to have a request body?

I'm writting a RESTful api, and at I'm thinking about the process of a user creating a key. I have the following possibilities:
GET request to /new/<keyname> - although it's very easy I think I won't use this, because I heard GET is for retrieving and/or listing information;
POST request to /<keyname> - This seemed to me easy and simple enough, but does not pass any data in the request body. Can I do it this way ? Is this weird ?
POST request to /keys passing in the request body "keyname=SomeKey" - Is this the correct way ?
I looked at this API from joyent and in all their PUT and POST requests they pass some data in the request body. Is this expected ? Is it really wrong not to require a request body in a PUT and POST request ?
I asked this question on the Http-WG. This was the most precise answer I got http://lists.w3.org/Archives/Public/ietf-http-wg/2010JulSep/0276.html
In summary, POST does not require a body. I would expect the same justification can be applied to PUT.
RFC2616 is the base RFC for HTTP 1.1
In the most general form, an HTTP message is this (note the optional body):
generic-message = start-line
*(message-header CRLF)
CRLF
[ message-body ]
start-line = Request-Line | Status-Line
Reading further gives this:
9.5 POST
The POST method is used to request that the origin server accept the
entity enclosed in the request as a new subordinate of the resource
identified by the Request-URI in the Request-Line. ...
and
9.6 PUT
The PUT method requests that the enclosed entity be stored under the
supplied Request-URI. ...
The fundamental difference between the POST and PUT requests is
reflected in the different meaning of the Request-URI. The URI in a
POST request identifies the resource that will handle the enclosed
entity. That resource might be a data-accepting process, a gateway to
some other protocol, or a separate entity that accepts annotations.
In contrast, the URI in a PUT request identifies the entity enclosed
with the request -- the user agent knows what URI is intended and the
server MUST NOT attempt to apply the request to some other resource.
Both POST and PUT include the phrase entity enclosed in the request.
Based on my reading, I believe that a body is desired (a non-normative description, I know) for both POST and PUT.
In the context of REST, POST is create and PUT is update. I can imagine creating an empty object (perhaps a placeholder for future information), but I don't imagine much use of an empty update.
It is not required. You can send a POST/PUT 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
Probably the best way is your third option: POST to /keys with keyname=SomeKey.
Here's why: You may wish to add another function to your API, for example create_new_user. It would then be difficult to tell the difference between a user trying to POST a key called create_new_user and a user trying to use the create_new_user function.
You are correct in saying that you should not be using GET to do this operation as the GET operation "SHOULD NOT have the significance of taking an action
other than retrieval." (RFC 2616).
To answer your question in one line. Yes it is expected to have Body/Content in body, but it is not required(Mandatory).
According to okHttp3 (an HTTP library for android): the following methods need a body: POST, PUT, PATCH, PROPPATCH (WebDAV) and REPORT (source). It even crashes if you try to do a request with the given methods without a body.

Is it possible to set some http headers while http-redirect(302 or 307)?

Is it possible to set some http headers while http-redirect(302 or 307)?
<?
header("some-header: xxx");
header("Location: http://other.domain.com/foo.php",TRUE,307);
?>
You can basically set whatever http headers you want either as the server or the client.
If you are indicating a redirect you should supply the Location header as your example suggests. You should also ensure that your response headers refer to that response rather than the resource that the client is being redirected to. i.e. your headers here could include Content-Length: 0, omit the Content-Type header and so on.
Not sure if this is what you're after - this question could do with a bit more detail.
You can always do the redirection 301/307.
There are ways to do it
1) Do it through java code :
response.setStatus(307);
response.setHeader("Location",url);
2) THe same thing can be done in JSPs.
A tip here is: Always use the setHeader function and not the addHeader function as they behave in different ways.

Resources