I'm trying to post a reply in a Team Discussion in SharePoint using the Lists webservice. I have tried the AddDiscussionBoardItem operation. Since the message parameter should be MIME, I create the thread by posting a message like:
Message-ID: <1343576290.0.1409922592343.JavaMail.foouser#foocomputer>
Subject: Test thread
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Thread-Index: Ac/JCq4D1Jh6s4l1SLGY/7pz8XIN2Q==
Body of test thread.
This works. But then I try to create a reply. Note the Thread-Index which is required according the webservice specification.
Message-ID: <1708591960.0.1409922780765.JavaMail.foouser#foocomputer>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Thread-Index: Ac/JCq4D1Jh6s4l1SLGY/7pz8XIN2QAAHBNL
Body of thread reply.
This gets posted, but instead of ending up as a reply, a new thread named "(no title)" is created. I thought the Thread-Index was the key, I have tried to implement it according ConversationIndex Property specification. To sum it up, the first 22 bytes (unencoded) should be same in the thread, with an extra 5 bytes extra for every level down. (An odd thing is that you post it base64-encoded, but get it back in hex.)
So, what's missing or is there another way of doing it?
I'm programming in Java but I don't think the challenge is language-specific.
Related
I'm working with STM32-microcontroller and C-languege and want to send to and receive the data from my website. I can receive the .txt file with the "GET" method from website via this code:
static const char http_request[] = "GET "WEBSITE_SUB_ADDRESS" HTTP/1.1\r\nHost: "WEBSITE_ADDRESS"\r\n\r\n";
net_sock_send(socket, (uint8_t *) http_request, len);
net_sock_recv(socket, (uint8_t *) buffer + read, NET_BUF_SIZE - read);
Now I want to send or upload the data to the website in a file with http-method (POST or PUT, ...). How can I do it?
You first need to decide if you want to use POST or PUT.
The PUT method completely replaces whatever currently exists at the target URL with something else. With this method, you can create a new resource or overwrite an existing one given you know the exact Request-URI. ...In short, the PUT method is used to create or overwrite a resource at a particular URL that is known by the client.
The HTTP POST method is used to send user-generated data to the web server. For example, a POST method is used when a user comments on a forum or if they upload a profile picture. A POST method should also be used if you do not know the specific URL of where your newly created resource should reside. ...In short, the POST method should be used to create a subordinate (or child) of the resource identified by the Request-URI.
from https://www.keycdn.com/support/put-vs-post
While connected to the server you would send a HTTP header just as you have done with the GET request that would look somthing like this:
POST /test HTTP/1.1\r\n
Host: www.myServer.com\r\n
Content-Type: text/plain\r\n
Content-Lenght: 8\r\n
Accept: */*\r\n
\r\n
someData
You might also want to check if the server recived the message by looking at the header that is sent back to you, it should include HTTP/1.1 200 OK.
Edit: to get it into a file try /test/mytext.txt but i dont have a way of testing if this works
A good place to test the request is Post Test Server V2. hope this helps
#Flynn Harrison
I tested your method as follows:
static const char http_request[] = "POST "SUB_ADDRESS" HTTP/1.1\r\n"
"Host: "HOST_ADDRESS"\r\n\r\n"
"Content-Type: text/plain\r\n"
"Content-Lenght: 13\r\n"
"Accept: */*\r\n"
"\r\n"
"Data for Write Test";
and then:
net_sock_setopt(socket, "tls_server_name", (uint8_t*)HOST_ADDRESS, sizeof(HOST_ADDRESS));
net_sock_open(socket, HOST_ADDRESS, TIME_SOURCE_HTTP_PORT, 0);
net_sock_send(socket, (uint8_t *) http_request, len);
net_sock_recv(socket, (uint8_t *) buffer + read, NET_BUF_SIZE - read);
When I tried "/test.txt" at SUB_ADDRESS, I get the HTTP / 1.1 200 OK message but immediately after receiving the file contents, in the same buffer, I receive the HTTP / 1.1 400 Bad Request message and I do not see any changes to the file. My response from server is as follows:
HTTP/1.1 200 OK
.
.
.
This is a Test.... (Text-File Content)
HTTP/1.1 400 Bad Request\r\nDate: Fri, 09 Aug 2019 09:03:56
.
.
.
In the site you mentioned, the POST method works well but its mechanism is not clear which I can use. I tried to test the POST method with this site and my device but got error "411 Length Required".
I'm working with a slightly unconventional API that is expecting a JSON body with a GET request and I have no control over this. Unfortunately, every time I attempt to make the request, it seems to completely disappear and never make it to the API. I originally wrote the request using a standard URLSession and then switched to try Alamofire in an attempt to fix it but ended with the same result. My request looks like this:
Alamofire.request("http://192.168.1.1:8000/connect/", method: .get, parameters: ["test": "test"], encoding: JSONEncoding.default)
.responseJSON { response in
let body = response.request?.httpBody
guard response.result.isSuccess else {
onCompletion(nil)
return
}
onCompletion(response.result.value as! [String : Any]?)
}
This exact code works for a different request where there is no JSON in the body, but seemingly the moment I add it, it just times out. This has already been discussed on the alamofire github repo (https://github.com/Alamofire/Alamofire/issues/1819) but the final comment with what should be working code isn't really any different to mine, so doesn't provide any help, nor do the other linked issues.
Printing the request with debugPrint gives me this curl command
$ curl -i \
-H "Content-Type: application/json" \
-d "{\"test\":\"test\"}" \
"http://192.168.1.1:8000/connect/"
Which is missing the -X GET flag, but when I add that in, the request works as expected and the server responds, so I know the API itself is working and is happy processing the JSON in the body, so I'm at a loss as to what's going on.
I've installed Timberjack to attempt to trace things, which didn't give me any more info at all, just what I already knew
Request: GET http://192.168.1.1:8000/connect/
Headers: [
Content-Type : application/json
Content-Length : 24
]
Although I'm not sure if it's supposed to be showing me the body as well which it isn't?
In both cases (URLSession and Alamofire) the request gives the following output which I don't see at any other time:
2017-01-22 23:31:09.797453 my-app[3755:1349066] [] nw_endpoint_flow_service_writes [2 192.168.1.1:8000 ready socket-flow (satisfied)] Write request has 4294967295 frame count, 0 byte count
2017-01-22 23:32:04.484182 my-app[3755:1349066] [] __tcp_connection_write_eof_block_invoke Write close callback received error: [89] Operation canceled
Anyone have any ideas on what's going on as I'm completely at a loss at this point.
Update
I've done some more digging. If I change the endpoint to https://httpbin.org/get then the request goes through just fine and I get a response. Whilst this kind of suggests the API server is refusing to process the request, it's still working with the cURL command so that can't really be the issue.
I also forgot to mention (although not sure it should make a difference) that the API I'm trying to communicate with is connected via an ad-hoc wifi. Other requests to it work just fine though so I can definitely communicate with it.
Update 2
So I've been able to switch the server to using POST instead of GET and unsurprisingly it now works, however I would still love to know of a solution to the original problem
URLSession and CFHTTPMessage cannot send a message body for a GET request. They send the content length for the body, but do not send the body itself. This results in a timeout.
In order to resolve this issue I've used libcurl to handle the GET requests which have a message body to my project. I use URLSession everywhere else. When you add a body to a request using libcurl it changes the request to a POST, but that can be changed back to a GET after setting the body and before submitting the request.
I have an Azure Mobile App backend working web service. I am trying to carry out basic crud operations. I understand that you can use a url like myapp/tables/object?zumo-api-version=2.0.0 and this works fine when I am getting data. However, when I want to put, delete etc it requires an id. If I type myapp/tables/object/dsjkfhsdjkfjsdfjkkdjf?zumo-api-version=2.0.0 for example where the string is the id I can carry out the operation. Similarly, if I enter an id in Swagger, I can also carry out the put operation. However, I am unsure as to how to go about adding the zumo-api-version details on the client side. How can I include the zumo version header in my project?
See Header Specification here:
https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-client-and-server-versioning/
The key ZUMO-API-VERSION may be specified in either the HTTP header or the query string. The value is a version string in the form x.y.z.
For example:
GET https://service.azurewebsites.net/tables/TodoItem
HEADERS: ZUMO-API-VERSION: 2.0.0
POST https://service.azurewebsites.net/tables/TodoItem?ZUMO-API-VERSION=2.0.0
So you could do:
$ curl -sv -H "ZUMO-API-VERSION: 2.0.0" \
http://{mobileapp}.azurewebsites.net/tables/todoitem
> GET /tables/todoitem HTTP/1.1
> Host: {mobileapp}.azurewebsites.net
> User-Agent: curl/7.49.1
> Accept: */*
> ZUMO-API-VERSION: 2.0.0
>
< HTTP/1.1 200 OK
[...]
[{
"id":"40b996d6-ec7f-4188-a310-0f02808e7093",
"createdAt":"2016-08-31T11:30:11.955Z",
"updatedAt":"2016-08-31T11:30:11.971Z",
"version":"AAAAAAAAG5s=",
"deleted":false,
"Yo_mobileapp":"Sup"
}]
Note ZUMO-API-VERSION: 2.0.0 passed in as Header.
If you're asking "Which is better?", there's no better. They do the same thing. That being said, it's probably easier and cleaner to send a Header for most use cases.
I'm trying to implement a simple DMS that can provide subtitle information to the DMR -LG SmartTV - using platinium library.
I already succeeded to render video on the DMR and i already found where the DMR receive the information of the subtitle associated to the video file.
Sample request from the DMR:
POST /upnp/services/ContentDirectory/control HTTP/1.1
HOST: 192.168.1.3:54444
CONTENT-LENGTH: 735
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-upnp-org:service:ContentDirectory:1#Browse"
USER-AGENT: Linux/2.6.39.4.ps-110224-lg1152 UPnP/1.0 DLNADOC/1.50 INTEL_NMPR/2.0 LGE_DLNA_SDK/1.6.0
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
<ObjectID>ea06</ObjectID>
<BrowseFlag>BrowseDirectChildren</BrowseFlag>
<Filter>#id,#parentID,#restricted,#childCount,dc:title,dc:creator,upnp:artist,upnp:class,dc:date,upnp:album,upnp:genre,res,res#size,res#duration,res#protection,res#bitrate,res#resolution,res#protocolInfo,res#nrAudioChannels,res#sampleFrequency,upnp:albumArtURI,upnp:albumArtURI#dlna:profileID, res#dlna:cleartextSize</Filter>
<StartingIndex>0</StartingIndex>
<RequestedCount>24</RequestedCount>
<SortCriteria></SortCriteria>
</u:Browse>
</s:Body>
</s:Envelope>
now the response from a valid DMS that support subtitle display is:
HTTP/1.1 200 OK
SERVER: WINDOWS/5.1 UPnP/1.0 DLNADOC/1.50 Nero-MediaHome/4.5.20.145
CONTENT-TYPE: text/xml; charset=utf-8
EXT:
DATE: Mon, 14 Jan 2013 22:12:35 GMT
TRANSFER-ENCODING: chunked
CONNECTION: Keep-Alive
...
<item id="ea13" parentID="ea06" restricted="1">
<dc:date>2012-10-25</dc:date>
<dc:title>video.avi</dc:title>
<upnp:album>Filmes</upnp:album>
<upnp:class>object.item.videoItem.movie</upnp:class>
<res
bitrate="257570" duration="1:37:32" nrAudioChannels="6"
protocolInfo="http-get:*:video/avi:DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000"
resolution="720x304" sampleFrequency="48000" size="1507196928">http://192.168.1.3:54444/server/80402875-CA74-4CCE-B7E0-D81CEF1913A2/D5E59F25/ea13?unknown-id</res>
<res protocolInfo="http-get:*:text/srt:*">http://192.168.1.3:54444/server/80402875-CA74-4CCE-B7E0-D81CEF1913A2/3A2C7131/ea13?sub=video.srt</res>
</item>
Now i'm trying to implement the same in my custom DMS, can anyone point me in the right direction or show any sample that implements subtitle info stored in res element as: srt_URL (content-type of response is text/srt)
Thanks
To add a SRT resource tag to UPnP item in Platinum, you should do at least the following. I don't claim the list being functional, complete or tested. It's just my best guess at what needs to be changed. If it doesn't immediately work as expected, i may not be able to help you more specifically. It's a navigation hint, not a driving assistance.
put your SRT file in the same folder as the media file, named the same way in some sensible way which would be easy for you to distinguish afterwards.
in PltMimeType.cpp add "srt","text/srt" to PLT_HttpFileRequestHandler_DefaultFileTypeMap. Platinum doesn't know SRT out of the box.
PltFileMediaServer.cpp is kinda dumb, it by default shows up all files found in a directory. It's an example, after all. You need to filter out SRTs from the visible listing by implementing PltFileMediaServer::ProcessFile filter.
still in PltFileMediaServer.cpp there is a method PLT_FileMediaServerDelegate::BuildFromFilePath. Here comes filepath which is the path of your media file (and ONLY that). Out of the filepath, you need to look in the folder whether there is a properly named subtitle file (with some NPT_File methods, look it up).
if there is, you must add extra PLT_MediaItemResource to the PLT_MediaObject* object. There is already one resource instance, but that's used exclusively for the media resource itself. Don't reuse it. You need to add another one, and IMO you need to set only resource.m_Uri (with BuildResourceUri) and resource.m_ProtocolInfo.
for m_ProtocolInfo, you need to call PLT_ProtocolInfo::GetProtocolInfo with parameter false so that the protocolInfo of your newly added <res> is not clobbered with DLNA profile id.
I already tried some different SOAP-messages, even one which has an empty header and body, but without success to get into my SoapHttpRouter-derived class :-(
Also, when I hit the .asmx-URL with the browser it comes to that error.. here detailed stack trace of the error:
[NotSupportedException: WSE003: The input was not a valid SOAP message.]
Microsoft.Web.Services2.Messaging.SoapHttpRouter.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object asyncState) +134
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8677954
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
I hope that someone is out there who had the same problem. I would appreciate your help very much!
Typically when I get that message it's because there is a server side error and it's sending the default HTML error page back instead of the properly formatted SOAP message.
I would try stepping through the server-side code (if possible) to make sure there aren't any problems.
Were you aware that WSE 2.0 is extremely obsolete? Even more so than WSE 3.0.
I recently ran into this issue. The solution for me was to add the SOAPAction HttpHeader to the request, so that the request header looked something like this:
POST <web service url> HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: <action url>
Host: <host>
Content-Length: xxx