Jersey matches regex pattern before the method type - regex

Is it possible to define 2 methods in Jersey with same regex but different type? (GET, PUT ..):
#GET
#Path("{key: .+}")
#Produces(MediaType.TEXT_PLAIN)
public Response root(String key) {
}
#PUT
#Path("{key: .+}")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.TEXT_PLAIN)
public Response publish(String key, FormDataMultiPart data) {
}
The first method should only reply for the key (with or without slashes)
curl -X GET "http://localhost/key
Jersey respond with 200 OK since it went to the GET method
curl -X GET "http://localhost/key/
Jersey respond with 200 OK since it went to the GET method
curl -X PUT -T file.txt "http://localhost/key
Jersey respond with 200 OK since it went to the PUT method
curl -X PUT -T file.txt "http://localhost/key/
Jersey respond with 200 OK since it went to the PUT method
curl -X PUT -T file.txt "http://localhost/key/folder/folder
Jersey respond with 405 Method Not Found since it went to the GET method
instead of the PUT (the get only respond to 1 folder level which is the 'key'
but i expected that jersey will go directly to the PUT since it suppose to check for the method type before the regex matching
Why the last one doesn't work? it seems Jersey first looks for regex even though it's a PUT request.

You say "Jersey respond with 405 Method Not Found since it went to the GET method instead of the PUT" but a 405 means that it didn't go to any method. Try changing your PUT method to:
#PUT
#Path("{key: .+}")
#Produces(MediaType.TEXT_PLAIN)
public Response publish(String key) {
}
And that should work. You then need to ensure that you provide the correct data as part of your CURL request to ensure that it matches the #Consumes annotation when you put it back in to the request.

Related

category_list param for test page creation request

Having created a test user for my app, I intend to create a test page by sending the following POST request to the Facebook API (some parts obviously replaced with dummies):
https://graph.facebook.com/v7.0/<TEST_USER_ID>/accounts?access_token=<APP_TOKEN>&name=Dummypage&category_enum=BANK&about="Text"&picture=<URL_TO_IMAGE>&cover_photo={"url": "<URL_TO_OTHER_IMAGE>"}&location={"city": "SomeCity","state": "SomeState","country": "DE"}&address="<ADDRESS>"&phone="<PHONE>"&category_list=[{"id": "133576170041936"} ,{"id": "145988682478380"}]
The problematic part of this is the category_list parameter, which I have attempted to pass in many forms already. Arriving at
category_list=[{"id": "133576170041936"} ,{"id": "145988682478380"}]
I finally no longer get the error that the param has to be an array - instead I get the following error: (#100) Param category_list[0] must be a valid ID string (e.g., \"123\") .
This is fairly confusing, as the IDs are taken from the response of an API response containing the page categories:
https://graph.facebook.com/v7.0/fb_page_categories?access_token=<TOKEN>
How should the parameter be correctly passed?
What I tried so far:
category_list=["145988682478380"]
category_list=[145988682478380]
Result: (#100) Invalid parameter
category_list=[{"id": "145988682478380"}]
category_list=[{"id": "145988682478380", "name": "Kreditgenossenschaft", "api_enum": "CREDIT_UNION"}] #full entry as listed in page categories response
Result: (#100) Param category_list[0] must be a valid ID string (e.g., "123")
Documentation references
Page category
Creating a test page via POST request
This curl command worked by me:
curl -i -X POST -H "Content-Type: application/json" -d "{ \"category_list\": [192803624072087, 145988682478380]}" "https://graph.facebook.com/v8.0/me?access_token=[page_access_token]"
So with the following JSON Body:
{
"category_list": [192803624072087, 145988682478380]
}

Unable to match a simple Soap body with 'x-mock-match-request-body' in Postman

Description
Unable to match a simple Soap body with x-mock-match-request-body.
To Reproduce
Steps to reproduce the behavior:
Create an example for a mock server with any url, any http verb and any response
e.g. POST {{url}}/test with the response:
{
"test":"test"
}
Add the following request body in the example:
<soap:Envelope>
</soap:Envelope>
Create a request pointed at the example url with the same body as the example body
Send the request
Add the header x-mock-match-request-body and give the value true
Send the request
Expected behavior
Step 4 is expected to return the example response as the body is not matched and the http verb and url path is correct - this works as expected
Step 6 is expected to return the example response as the body is the same as specified in the example and the http verb and url path is correct - this does NOT work as expected
Screenshots
Mock example:
Mock example headers and response:
Request with body matching:
Headers and response:
Headers and response without body matching:
App Type [Native App]
Postman Version [7.24.0]
OS: [Windows 10 Enterprise]
I am able to match a JSON-body without issue. Has anyone experienced this when using SOAP?
I added the header Content-type: Application/xml to both the example and the request and it worked.

Can libcurl.net be used to post a new page to confluence?

I'm just getting started using the REST API to create pages.
I'm trying to configure a basic example and I thought of using libcurl.net to do it.
Does anyone see any reason why that wouldn't work?
UPDATE:
Here is what I have so far adapted from the curllib.net "bookpost" example
Option Explicit On
Imports System.IO
Imports System.Net
Imports SeasideResearch.LibCurlNet
Public Class CurlOperations
Public Shared Sub CurlPost()
Try
Dim credUserName As String = "username"
Dim credPassword As String = "password"
Dim response As String = Nothing
Dim outputStdErr As Stream = Nothing
Curl.GlobalInit(CURLinitFlag.CURL_GLOBAL_ALL)
Dim easy As Easy
easy = New Easy
' Set up write delegate
Dim wf As Easy.WriteFunction
wf = New Easy.WriteFunction(AddressOf OnWriteData)
easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf)
'Authentication
easy.SetOpt(CURLoption.CURLOPT_HTTPAUTH, CURLhttpAuth.CURLAUTH_BASIC)
easy.SetOpt(CURLoption.CURLOPT_USERPWD, credUserName & ":" & credPassword)
'disable ssl peer verification
easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, False)
'Header
easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER, "Content-Type: application/json; charset=utf-8")
' Simple post - with a string
easy.SetOpt(CURLoption.CURLOPT_POSTFIELDS, WikiTools.CommREST.WebToCF.PostCurl())
' and the rest of the cURL options
easy.SetOpt(CURLoption.CURLOPT_USERAGENT, ".NET Framework Client")
easy.SetOpt(CURLoption.CURLOPT_URL, "https://domain.com/confluence/rest/api/content/")
easy.SetOpt(CURLoption.CURLOPT_POST, True)
response = easy.Perform().ToString
LoggingAndActivites.WriteLog("Response: " & response, GetFunctionName.GetCallerName, True, True)
Catch ex As Exception
LoggingAndActivites.WriteLog("Exception: " & ex.ToString, GetFunctionName.GetCallerName, True, True)
End Try
Curl.GlobalCleanup()
End Sub
' Called by libcURL.NET when it has data for your program
Public Shared Function OnWriteData(ByVal buf() As Byte, ByVal size As Int32, ByVal nmemb As Int32, ByVal extraData As Object) As Int32
LoggingAndActivites.WriteLog(System.Text.Encoding.UTF8.GetString(buf), GetFunctionName.GetCallerName, True, True)
Return size * nmemb
End Function
End Class
I am getting connected because if I remove the username and password I get a response through the "onWriteData" function as follows:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head>
<title>401 Unauthorized</title>
</head>
<body>
<h1>Unauthorized</h1>
<p>This server could not verify that you
are authorized to access the document
requested. Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.</p>
<hr>
<address>Apache Server at domain.com Port 7080</address>
</body>
</html>
The problem now is that if I correctly log on I'm not getting any response other than the "CURLE_OK" from the "easy.Perform()" function.
It's good because I know it's working to some degree.
According to the libcurl.net docs : http://www.libcurl.org/
libcurl also supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, and user+password authentication.
So I guess you should be able to make a REST API call with it. I have used curl (the linux version) to create and update pages, using something like this:
curl --globoff --insecure --silent -u username:password -X PUT -H 'Content-Type: application/json' --data #body.json confluenceRestAPIURL/pageId
where body.json is a file containing the data to update the page.
I wrote a blog about this here: https://javamemento.blogspot.no/2016/05/jira-confluence-3.html
You can get the code here: https://github.com/somaiah/jira-confluence-graphs
So it does work
Here is what I added/changed to make the code above work
'I added an Slist to store the header items (I only had one)
Dim slistHeaders As New Slist
slistHeaders.Append("Content-Type: application/json")
'Then I added the slist to the HTTPHEADER
easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER, slistHeaders)
THINGS TO WATCH FOR:
(1) The URL of course is the number one thing
In my case I was using was https://domain.com/confluence/rest/api/content/ because the Confluence Documentation assumes you would be using the root domain name (as did I)
However, what I didn't know was that the URL I was given to test was already directing me into the "confluence" folder.
So my URI needed to be https://domain.com/rest/api/content/ instead
(2) An indicator that your HTTPHEADER needs to be put into an Slist is this return from the server: 415 Unsupported Media Type
(3) Be sure NOT to use the CURLOPT_HEADER property. If you are seeing this header in your responses you need to make sure it's not used:
HTTP/1.1 500 Internal Server Error
Date: Sun, 22 May 2016 17:50:32 GMT
Server: Apache
Content-Location: 500.en-GB.html
Vary: negotiate,accept-language
TCN: choice
Accept-Ranges: bytes
Content-Length: 7575
Connection: close
Content-Type: text/html; charset=UTF-8
Content-Language: en-gb
Refer to my post here for an explanation of why: CURLOPT_HEADER
(4) Lastly, when you build your app if you receive this error:
An unhandled exception of type 'System.AccessViolationException' occurred in libcurl.NET.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
This is caused by libcurl.net process not being cleaned up.
The "cleanup()" method isn't available in the DLL, despite being lsited in the examples.
So instead use EASY.Dispose() at the end of your procedure and this error will stop. (I kept the "GlobalCleanup()" method in just for good measure)
(5) Ironically I went the way of using CURL because I thought that the Confluence interface might require it.
But it appears now that it doesn't and that you can simply use the "HttpWebRequest" Class in .NET to get the same results.
However, the Jury is still out because the "lightweight" test server I was assigned to crashed and I'm waiting for them to fix it so I can verify this.
Either Way I hope all this helps someone
M

Adding headers to HTTP request using cfhttp's addParam method

I'm new to Coldfusion and can't understand why I'm having so much trouble adding a couple of headers to an http request that I'm making with cfhttp. I'm trying to write the request using cfscript, and from everything I've read I should be able to simply do:
httpService.addParam(type="header", name="Content-Type", value="application/json");
or
httpService.addParam(type="header", name="Authorization", value=local.authPasscode);
But the outgoing request doesn't seem to contain these headers. I can tell it's not working because:
I'm getting errors back in my response
I'm doing a writeDump(GetHttpRequestData()), which shows all the details of the request (and this output does not show the Authorization header at all and shows the Content-Type header as:
multipart/form-data; boundary=----WebKitFormBoundaryZs9TyOQV02N3fQop
I also seem to have difficulty adding the body of the message in a similar way so I'm thinking I'm doing something wrong with addParam(). I'm attempting that like so:
httpService.addParam(type="body", value="hello");
Again, the response I get back has a bunch of missing field errors and the output of writeDump(GetHttpRequestData()) shows a missing body.
Am I supposed to be able to use addParam() in this way?
Full code:
httpService = new http();
httpService.setMethod("POST");
httpService.setUrl(application.config.beanstream.postURL);
local.authPasscode = "Passcode " & ToBase64(application.config.beanstream.merchantid & ":" & application.config.beanstream.APIPasscode, "utf-8");
// Set headers.
httpService.addParam(type="header", name="Authorization", value=local.authPasscode);
httpService.addParam(type="header", name="Content-Type", value="application/json");
// Construct the message body.
local.body = {
"test": "hello"
};
httpService.addParam(type="body", value=SerializeJSON(local.body));
writeDump(GetHttpRequestData());
local.result = httpService.send().getPrefix();
Update:
Okay, so I changed my postURL to that of another local page and on that page I'm using GetHttpRequestData() to log the method, protocol, headers and content all out to a file. Here's what I get:
POST
HTTP/1.1
{host={www.mysite.com},user-agent={ColdFusion},connection={close},content-length={16},authorization={Passcode Mjc1ODMwMDAwOjIwMTI5NGUwMjI2MzQxMzlBZjBFMDE2RmViRjg0RDAz},content-type={application/json}}
{"test":"hello"}
So it looks to me like I am indeed correctly sending a POST to the correct URL and the headers are getting set correctly as well. My content even seems like it's there so this is starting to feel like I'm sending invalid body data to the API. Unless anybody can think of anything else to check I'm going to investigate that further.
instead of
local.body = {
"test": "hello"
};
try
local.body = {};
local.body["test"] = "hello";
then you can
SerializeJSON(local.body)

Django POST sub-dictionaries

I'm making the following request through command-line cURL:
curl -X POST http://localhost:8000/api/places/ -vvvv -d "place[name]=Starbucks"
However, when I try to access the parameters by calling
request.POST.getlist('place')
I get an empty array as a response. How can I access the sub-dictionary which I can then pass to the ORM?
Thanks,
Jamie
HTTP data elements can't have sub-elements. The data you have posted - as shown in the querydict - has been interpreted as a single element with key "place[name]" and value "Starbucks". So you can get it with request.POST["place[name]"].
It looks like you are sending a string, in that case try:
request.POST.get('place[name]')
If your are simulating a dropdown list you should send "place=Starbucks", however if you are trying to send an array you should try to convert you string to an array inside your python script.
In your command you can get ride of "-X POST" as the parameter -d is already an HTTP POST:
curl --help
...
-d/--data <data> HTTP POST data (H)
curl manual:
http://curl.haxx.se/docs/manual.html