How to send this PUT-request to prestashop?

2019-08-07 03:30发布

问题:

I am working with Prestashop web service. I am trying to send a PUT (update) request to the API but with no luck. My request seems to be set up in the 'wrong' way (i.e. not in the way the server expects) Since Prestashop is open-source I took a look at the source code, specifically when it recieves a PUT request it does the following (I don't write php-code):

$input_xml = null;
// if a XML is in PUT or in POST
if (($_SERVER['REQUEST_METHOD'] == 'PUT') || ($_SERVER['REQUEST_METHOD'] == 'POST')) {
    $putresource = fopen("php://input", "r");
    while ($putData = fread($putresource, 1024)) {
        $input_xml .= $putData;
    }
fclose($putresource);
  }
if (isset($input_xml) && strncmp($input_xml, 'xml=', 4) == 0) {
    $input_xml = substr($input_xml, 4);
}

From the code above I understood that my data should look something like this: xml=<data><here></here></data> but I don't know where to put this, should it be in the request-body or embedded in the url? is the "xml=" implicit when you send a request with Content-Type = text/xml? I did try different combinations of the request and still getting the same 404 error. I tried this:

let updateOrderState (orderId:int64) (stateId:int64) (credentials:AuthInfo) = 
    // url looks like this: http://www.webstoreexample.com/entity/id
    let auth = BasicAuth credentials.Key ""
    let orderApi = credentials.Api + "/orders/" + orderId.ToString();
    let orderAsXml = Http.RequestString(orderApi, httpMethod = "GET", headers = [auth])
    let xml = Order.Parse(orderAsXml).XElement // at this point, I have the data
    xml.Element(XName.Get("order")).Element(XName.Get("current_state")).SetValue(stateId) // field 'current_state' gets modified
    let xmlData = xml.ToString()
    // HERE the put request
    Http.RequestString(url = credentials.Api + "/orders", 
                       headers = [ auth; 
                                   "Content-Type","text/xml" ],         
                       httpMethod= HttpMethod.Put,
                       body= HttpRequestBody.TextRequest(xmlData))

Variations on the PUT-request didn't work as well, here I changed the request body from TextRequest into FormValues:

Http.RequestString(url = credentials.Api + "/orders", 
                   headers = [ auth; 
                               "Content-Type","text/xml" ],         
                   httpMethod= HttpMethod.Put,
                   body= HttpRequestBody.FormValues ["xml", xmlData]) // xml=xmlData

Another thing I tried is adding the id to the url (even tho in the docs they say that this is not required):

Http.RequestString(url = credentials.Api + "/order/" + orderId.ToString(), // added the id to the url
                   headers = [ auth; 
                               "Content-Type","text/xml" ],         
                   httpMethod= HttpMethod.Put,
                   body= HttpRequestBody.FormValues ["xml", xmlData]) // xml=xmlData

Specifically, I am tring to the update the value of the current_state node of an order. Getting the data and modifying it works as expected but sending the modified data doesn't seem to work and I still recieve the 404: Not found error

Any Help on this would be greatly apprecited!

回答1:

Okay, I just tested it with library and example that I give in comments, also I repetead same requests using CURL with same positive results, so there is nothing PHP language specific. I think you need just repeat same Headers/Body in your application.

HTTP REQUEST HEADER
PUT /16011/api/orders/8 HTTP/1.1
Authorization: Basic TlpCUEJKTkhaWFpFMzlCMVBDTkdTM1JQN0s2NTVVQ0Y6
Host: localhost
Accept: */*
Content-Length: 2411
Content-Type: application/x-www-form-urlencoded

XML SENT
<?xml version="1.0" encoding="UTF-8"?>
<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<order>
    <id>8</id>
    <id_address_delivery xlink:href="http://localhost/16011/api/addresses/5">5</id_address_delivery>
    <id_address_invoice xlink:href="http://localhost/16011/api/addresses/5">5</id_address_invoice>
    <id_cart xlink:href="http://localhost/16011/api/carts/8">8</id_cart>
    <id_currency xlink:href="http://localhost/16011/api/currencies/1">1</id_currency>
    <id_lang xlink:href="http://localhost/16011/api/languages/1">1</id_lang>
    <id_customer xlink:href="http://localhost/16011/api/customers/2">2</id_customer>
    <id_carrier xlink:href="http://localhost/16011/api/carriers/3">3</id_carrier>
    <current_state xlink:href="http://localhost/16011/api/order_states/2" notFilterable="true">10</current_state>
    <module>bankwire</module>
    <invoice_number>0</invoice_number>
    <invoice_date>0000-00-00 00:00:00</invoice_date>
    <delivery_number>0</delivery_number>
    <delivery_date>0000-00-00 00:00:00</delivery_date>
    <valid>0</valid>
    <date_add>2015-09-17 08:29:17</date_add>
    <date_upd>2015-10-20 03:45:13</date_upd>
    <shipping_number notFilterable="true"></shipping_number>
    <id_shop_group>1</id_shop_group>
    <id_shop>1</id_shop>
    <secure_key>45838497c9182b0d361473894092de02</secure_key>
    <payment>Bank wire</payment>
    <recyclable>0</recyclable>
    <gift>0</gift>
    <gift_message></gift_message>
    <mobile_theme>0</mobile_theme>
    <total_discounts>0.000000</total_discounts>
    <total_discounts_tax_incl>0.000000</total_discounts_tax_incl>
    <total_discounts_tax_excl>0.000000</total_discounts_tax_excl>
    <total_paid>24.450000</total_paid>
    <total_paid_tax_incl>24.450000</total_paid_tax_incl>
    <total_paid_tax_excl>23.510000</total_paid_tax_excl>
    <total_paid_real>0.000000</total_paid_real>
    <total_products>16.510000</total_products>
    <total_products_wt>17.170000</total_products_wt>
    <total_shipping>7.280000</total_shipping>
    <total_shipping_tax_incl>7.280000</total_shipping_tax_incl>
    <total_shipping_tax_excl>7.000000</total_shipping_tax_excl>
    <carrier_tax_rate>4.000</carrier_tax_rate>
    <total_wrapping>0.000000</total_wrapping>
    <total_wrapping_tax_incl>0.000000</total_wrapping_tax_incl>
    <total_wrapping_tax_excl>0.000000</total_wrapping_tax_excl>
    <round_mode>2</round_mode>
    <conversion_rate>1.000000</conversion_rate>
    <reference>ECHCBFWGR</reference>
<associations></associations>
</order>
</prestashop>