I want to get get the contents from a webpage but the user sees different information depending if he is logged or not. I want to send header information with curl to simulate that the use is logged in.
I inspected the network and these are the response headers:
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:close
Content-Type:text/html
Date:Tue, 13 Jun 2017 08:08:52 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Location:http://dims-92.com/ClientNewsPage
Pragma:no-cache
Server:Apache/2.2.3 (CentOS)
Transfer-Encoding:chunked
X-Powered-By:PHP/5.5.30
And there is this request payload:
------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="SubmitControlId"
Auto_CAuthenticate_LogIn_LogIn_Standart
------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="ParameterInfo"
undefined
------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="FC_CEShop_SearchControl_SearchInput"
------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="FC_CAuthenticate_LogIn_UsernameInput"
user
------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="FC_CAuthenticate_LogIn_PasswordInput"
password
------WebKitFormBoundaryaSWkHLJeD9EymCJb--
I have tried this:
$url = "http://dims-92.com/ClientDisplayProductFolder?param=4553686f703a434e493d3935343b434e494c3d3b5649443d3b543d42473b";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryaSWkHLJeD9EymCJb',
'Content-Length: 671',
'------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="SubmitControlId"
Auto_CAuthenticate_LogIn_LogIn_Standart
------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="ParameterInfo"
undefined
------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="FC_CEShop_SearchControl_SearchInput"
------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="FC_CAuthenticate_LogIn_UsernameInput"
user
------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="FC_CAuthenticate_LogIn_PasswordInput"
password
------WebKitFormBoundaryaSWkHLJeD9EymCJb--'
));
$content = curl_exec($ch);
echo $content;
but the page I see just says: Bad Request
Your browser sent a request that this server could not understand.
Request header field is missing ':' separator.
------WebKitFormBoundaryaSWkHLJeD9EymCJb
You can't post headers like this, they have to be in an array like so :
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: multipart/form-data',
'Content-Length: 671',
'Content-Disposition: form-data',
....
));
The problem is that you post the entire payload (things like boundary=----WebKitFormBoundaryaSWkHLJeD9EymCJb'), which is invalid.
your code is confusing the requests' HTTP HEADERS and the HTTP BODY
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Length: 671
these are parts of the HTTP REQUEST HEADERS, and indeed goes into the CURLOPT_HTTPHEADER.
Content-Disposition: form-data; name="SubmitControlId"
Auto_CAuthenticate_LogIn_LogIn_Standart
------WebKitFormBoundaryaSWkHLJeD9EymCJb
Content-Disposition: form-data; name="ParameterInfo"
undefined
this is part of the HTTP REQUEST BODY, the body does not go in CURLOPT_HTTPHEADER.
now, contrary to what Julien Lachal says in https://stackoverflow.com/a/44517070/1067003 , you can actually encode the entire request body yourself (using CURLOPT_POST or CURLOPT_INFILE), but when using multipart/form-data or application/x-www-form-urlencoded encoding, its easier, safer, and less error prone, to let curl encode it for you. (the usual reason for encoding it yourself, is when POSTing to a JSON API requiring content-type: application/json, curl does not support encoding to JSON automatically.)
to tell curl to do it for you, simply use CURLOPT_POST and CURLOPT_POSTFIELDS, like this:
curl_setopt_array ( $ch, array (
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array (
'SubmitControlId' => 'Auto_CAuthenticate_LogIn_LogIn_Standart',
'ParameterInfo' => 'undefined',
'FC_CEShop_SearchControl_SearchInput' => '',
'FC_CAuthenticate_LogIn_UsernameInput' => 'user',
'FC_CAuthenticate_LogIn_PasswordInput' => 'password'
)
) );
now libcurl will automatically multipart/form-data-encode it, and set the correct content-type, and set the correct content-length header, and the actual HTTP request will look like:
Http Request Headers:
POST / HTTP/1.1
Host: 127.0.0.1:8080
Accept: */*
Content-Length: 686
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------b6890d3827808ee1
Http Request Body:
--------------------------b6890d3827808ee1
Content-Disposition: form-data; name="SubmitControlId"
Auto_CAuthenticate_LogIn_LogIn_Standart
--------------------------b6890d3827808ee1
Content-Disposition: form-data; name="ParameterInfo"
undefined
--------------------------b6890d3827808ee1
Content-Disposition: form-data; name="FC_CEShop_SearchControl_SearchInput"
--------------------------b6890d3827808ee1
Content-Disposition: form-data; name="FC_CAuthenticate_LogIn_UsernameInput"
user
--------------------------b6890d3827808ee1
Content-Disposition: form-data; name="FC_CAuthenticate_LogIn_PasswordInput"
password
--------------------------b6890d3827808ee1--
however, note that many websites doesn't support multipart/form-data and/or prefer application/x-www-form-urlencoded encoding. to use that, use http_build_query on the data to CURLOPT_POSTFIELDS, like this:
curl_setopt_array ( $ch, array (
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query ( array (
'SubmitControlId' => 'Auto_CAuthenticate_LogIn_LogIn_Standart',
'ParameterInfo' => 'undefined',
'FC_CEShop_SearchControl_SearchInput' => '',
'FC_CAuthenticate_LogIn_UsernameInput' => 'user',
'FC_CAuthenticate_LogIn_PasswordInput' => 'password'
) ),
CURLOPT_URL => 'http://127.0.0.1:8080'
) );
now the actual HTTP request looks like this:
HTTP request headers:
POST / HTTP/1.1
Host: 127.0.0.1:8080
Accept: */*
Content-Length: 204
Content-Type: application/x-www-form-urlencoded
HTTP request body:
SubmitControlId=Auto_CAuthenticate_LogIn_LogIn_Standart&ParameterInfo=undefined&FC_CEShop_SearchControl_SearchInput=&FC_CAuthenticate_LogIn_UsernameInput=user&FC_CAuthenticate_LogIn_PasswordInput=password
Related
So I'm trying to mime the following:
------WebKitFormBoundarygLmTBM5HATvn9tpA
Content-Disposition: form-data; name="name"
p1bieoilebde1ra71v4tm2rlb3h.png
------WebKitFormBoundarygLmTBM5HATvn9tpA
Content-Disposition: form-data; name="file"; filename="watch.png"
Content-Type: image/png
------WebKitFormBoundarygLmTBM5HATvn9tpA--
My code looks like this
$cfile = new CURLFile(realpath(dirname(__FILE__) . "/../images/watch.png"));
$to_post = array ('file' => $cfile);
curl_setopt($ch, CURLOPT_POSTFIELDS, $to_post);
And it's not working, any help?
I have HTTP PUT API but cannot retrieve from the request. Input::all() returns empty. Can you share how to do it? I confirmed that $request had form-data.
public function update(Request $request, $id)
{
Log::info(Input::all()); // empty
Log::info($id); // 1001
Log::info($request);
}
$request ->
local.INFO: PUT /v1/shops/1001 HTTP/1.1
.
.
.
------WebKitFormBoundary2B26VoCplFAB8W36
Content-Disposition: form-data; name="item_id"
9001
------WebKitFormBoundary2B26VoCplFAB8W36
Content-Disposition: form-data; name="name"
tokyo
Route.php
<?php
Route::resource('v1/shops', 'ShopController');
?>
Detail
$request ->
local.INFO: PUT /v1/shops/1001 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: ja,en;q=0.8,en-US;q=0.6
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 332
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryAchDYDABHI1GDUeu
Cookie: XXXXXXXXXXXXXX
Host: XXXXXXXXXXXXXX
Origin: chrome-extension://aicmkgpgakddgnaphhhpliifpcfhicfo
Postman-Token: 434976e3-3476-3dcd-3689-7048d523dd20
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
------WebKitFormBoundary2B26VoCplFAB8W36
Content-Disposition: form-data; name="item_id"
9001
------WebKitFormBoundary2B26VoCplFAB8W36
Content-Disposition: form-data; name="name"
tokyo
I found it. I should have selected "x-xxx-form-urlencoded". not "form-data"
I got this form data and could retrieve by Input::all()
user_id=1&address=2&tag=3
This issue a was clue. https://github.com/postmanlabs/postman-app-support/issues/8
when I post the reply in a forum, I use live http header to view parameter which used to post the reply.
but, the headers no parameter. but, there are some header like this:
Content-Length: 1115
-----------------------------5959623329472
Content-Disposition: form-data; name="subject"
the title of reply
-----------------------------5959623329472
Content-Disposition: form-data; name="message"
the content of reply
how to post the headers with curl ? my code don't work
curl_setopt($ch, CURLOPT_HTTPHEADER, array('POST /post HTTP/1.1',
'Referer: http://*****.n-stars.org/post?t=4221&mode=reply',
'Content-Disposition: form-data; name="subject"
test lagi kk 2',
'Content-Disposition: form-data; name="message"
test lagi ya kk 8)' ));
please help me :D
These are not headers, If you are trying to make multipart post request, this should be content of your request body. In headers you should only inform endpoint about multipart request and boundary between parts:
// Headers
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Referer: http://*****.n-stars.org/post?t=4221&mode=reply',
'Content-Type: multipart/form-data, boundary=5959623329472',
'Content-Length: 1115'
));
// Body
curl_setopt($ch, CURLOPT_POSTFIELDS,
'--5959623329472
Content-Disposition: form-data; name="subject"
test lagi kk 2
--5959623329472
Content-Disposition: form-data; name="message"
test lagi ya kk 8)
--5959623329472--'
);
More about multipart requests: http://www.faqs.org/rfcs/rfc1867.html
Is is possible to create and send a similar HTTP-request using the POST-method in JavaScript?
POST register.jsp HTTP/1.1
Host: hi/iq
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.2) Gecko/20021126
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1
Accept-Language: en-us, en;q=0.50
Accept-Encoding: gzip, deflate, compress;q=0.9
Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66
Keep-Alive: 300
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------29772313742745
Content-Length: 452
-----------------------------29772313742745
Content-Disposition: form-data; name="name"
J.Doe
-----------------------------29772313742745
Content-Disposition: form-data; name="email"
abuse#spamcop.com
-----------------------------29772313742745
Content-Disposition: form-data; name="file-upload"; filename="test.txt"
Content-Type: text/plain
test data with some high ascii: ¿Como estás?
-----------------------------29772313742745--
The most important things I need are in the last 13 lines (form text data + form file data).
The data (text+file) are to be retrieved in a PHP file serverside.
I have already tried using XMLHttpRequest and Formdata, but I can't get it working properly.
The attempt that makes most sense imo is:
var fd3 = new FormData();
fd3.append('mode', 'end'); // set $_POST['mode']="end"
fd3.append('file', image.jpg); // set $_FILES['file']=image.jpg
var xhr3 = new XMLHttpRequest();
xhr3.open("POST", "pages/upload_arc3d.php", false);
xhr3.setRequestHeader("Content-type", "multipart/form-data");
xhr3.send(fd3);
I've been stuck on this problem for several hours: I'm using PHP and cURL to write a sort of PHP proxy. Almost everything works fine, setting cookies, handling redirects, and submitting forms using POST.
Basically, I'm trying to mirror a remote website with my local proxy. To do so, I redirect every request to http://localhost/resource to http://localhost/proxy.php?url=http://remotesite.com/resource that will fetch the resource on the remote website. The redirect is handled by a 404 error page on .htaccess but I guess that using mod_rewrite would not change things.
I'm testing my proxy on a complex application (the latest version of WordPress) deployed on a remote server. The WordPress login works fine and uses POST. However, I found a page where updating a form does not work, and for which all the POST data is not sent at all to the server.
Here is what I see with wireshark listening on the loopback interface:
POST /proxy/wp-admin/media.php?attachment_id=691&action=edit HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.23) Gecko/20110921 Ubuntu/10.04 (lucid) Firefox/3.6.23
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Referer: http://localhost/proxy/wp-admin/media.php?attachment_id=691&action=edit
Cookie: [snip]
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 501
attachments%5B691%5D%5Bmenu_order%5D=0&attachments%5B691%5D%5Bpost_title%5D=fb&attachments%5B691%5D%5Bimage_alt%5D=&attachments%5B691%5D%5Bpost_excerpt%5D=&attachments%5B691%5D%5Bpost_content%5D=foobar&attachments%5B691%5D%5Burl%5D=http%3A%2F%2Flocalhost%2Fproxy%2Fwp-content%2Fuploads%2F2009%2F04%2Ffb.gif&save=Aggiorna+media&post_id=&attachment_id=691&action=editattachment&_wp_original_http_referer=&_wpnonce=02caf30462&_wp_http_referer=%2Fwp-admin%2Fmedia.php%3Fattachment_id%3D691%26action%3Dedit
HTTP/1.1 200 OK
Date: Wed, 19 Oct 2011 16:18:56 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.10
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 5441
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
[content]
While, what I see if listening on the interface connected to the internet is:
POST /wp-admin/media.php?attachment_id=691&action=edit HTTP/1.1
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.23) Gecko/20110921 Ubuntu/10.04 (lucid) Firefox/3.6.23
Host: www.remotesite.com
Accept: */*
Referer: http://www.remotesite.com/wp-admin/media.php?attachment_id=691&action=edit
Cookie: [snip]
X-Forwarded-For: 127.0.0.1
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Date: Wed, 19 Oct 2011 16:25:13 GMT
Server: LiteSpeed
Connection: close
X-Powered-By: PHP/5.2.17
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Last-Modified: Wed, 19 Oct 2011 16:25:13 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
X-Frame-Options: SAMEORIGIN
Content-Type: text/html; charset=UTF-8
[content]
As you see my proxy is not transmitting the post data to the remote server.
I expect the problem to be related to the encoding of the POSTDATA, as POST variables in this case are in an array (attachments[691][menu_order]=0; attachments[691][post_content]=foobar and so on...).
I tried several changes as suggested by similar posts but haven't managed to change the behavior of the script at all. All this because apparently the first (local) POST sends the data to localhost, but cURL is unable to fetch the POST data (indeed, file_get_contents("php://input") in the code below reads 0 bytes).
I paste here part of my code hoping somebody can help me:
$ch = curl_init( $url );
$headers = array();
if ( isset($_SERVER['CONTENT_TYPE']) ) {
// commenting this out or changing to multipart/form-data does not change anything
array_push($headers, "Content-Type: ".$_SERVER['CONTENT_TYPE'] );
}
if ( count($headers) > 0 ) {
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
}
$postdata = file_get_contents("php://input"); //this turns out to be empty - and so is $_POST
//REQUEST METHOD: since pages are redirected from a 404 error page, we have to handle
//a redirect, so the real method is specified in REDIRECT_REQUEST_METHOD
if ( isset($_SERVER['REDIRECT_REQUEST_METHOD']) && isset($postdata) ){
if ($_SERVER['REDIRECT_REQUEST_METHOD'] == 'POST'){
curl_setopt( $ch, CURLOPT_POST, true );
}
}
else{
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST' ){
curl_setopt( $ch, CURLOPT_POST, true );
}
}
if ( isset($_SERVER['CONTENT_LENGTH'] ) && $_SERVER['CONTENT_LENGTH'] > 0 ) {
curl_setopt( $ch, CURLOPT_POSTFIELDS, $postdata );
}
//set cookies
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookietofwd');
curl_setopt($ch, CURLOPT_COOKIEFILE,'/tmp/cookietofwd');
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $ch, CURLOPT_HEADER, true );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
$out=curl_exec( $ch );
[...]
Why don't you get your POST data from $_POST? The application/x-www-form-urlencoded header appears to be an AJAX request instead of a regular POST, which I am not sure how it is handled by php://input.
You could so something like:
curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($_POST) );
Is there a specific reason why you want this in PHP? Why don't you just use nginx? (http://nginx.org/en/)
It will probably do a better job (and faster).