-
Notifications
You must be signed in to change notification settings - Fork 370
Allow IXI Modules to dictate response's content-type. #743
base: dev
Are you sure you want to change the base?
Conversation
To test the IXI part, you can take https://github.com/brunoamancio/TangleNet , an IXI module which provides the client with web content from the Tangle. Just query from the browser (get request): |
It might also be possible to use gson to convert the query parameters to json. That way I can save some code. But for now I haven't tried it yet. I can analyse the possibility to improve that. (DONE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please review change requests
Set<String> keySet = queryParameters.keySet(); | ||
|
||
for (String key : keySet) { | ||
String param = queryParameters.get(key).getFirst(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like concatenated gets...
Can you seperate to two lines?
|
||
for (String key : keySet) { | ||
String param = queryParameters.get(key).getFirst(); | ||
queryParamsBody += "\"" + key + "\" : " + "\"" + param + "\","; // Json property |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are still using Java 8,
So can you use StringBuilder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've used gson to convert the parameters. It looks cleaner now.
@@ -201,14 +225,18 @@ private AbstractResponse process(final String requestString, InetSocketAddress s | |||
} | |||
|
|||
if (instance.configuration.string(DefaultConfSettings.REMOTE_LIMIT_API).contains(command) && | |||
!sourceAddress.getAddress().isLoopbackAddress()) { | |||
!exchange.getSourceAddress().getAddress().isLoopbackAddress()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
concatenated gets...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will do that, although the extra variable will be set even when the first condition isn't met. That means we are trading performance for maintainability.
return AccessLimitedResponse.create("COMMAND " + command + " is not available on this node"); | ||
} | ||
|
||
log.debug("# {} -> Requesting command '{}'", counter.incrementAndGet(), command); | ||
|
||
switch (command) { | ||
case "storeMessage": { | ||
if(!iotaAPIHeaderDefined(exchange)){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this always appear?
Instead of copy/pasting it can you write it once before the switch
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is to not require the API version header for calls to IXI modules. Due to the current use of a switch we have 3 options:
1 - Paste the check for every API call, except call to IXI modules (which is what I've done)
2 - Refactor the current logic to use command pattern
3 - Use a Map structure to map command names to API calls (kind of a command pattern)
I can refactor the existing command structure, but that should be done in another PR.
String response = null; | ||
if(res instanceof IXIResponse){ | ||
final String content = ((IXIResponse)res).getContent(); | ||
if(content != null && !content.equals("")){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should " "
pass?
Use StringUtils.isNotEmpty()
or StringUtils.isNotBlank()
according to your answer
} | ||
|
||
public String getResponseContentType() { | ||
Object fieldObj = getResponseMapper().get("contentType"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
concatenated gets
|
||
public String getResponseContentType() { | ||
Object fieldObj = getResponseMapper().get("contentType"); | ||
String fieldValue = fieldObj == null || "".equals(fieldObj) ? getdefaultContentType() : fieldObj.toString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should " "
pass?
Use StringUtils.isNotEmpty()
or StringUtils.isNotBlank()
according to your answer
|
||
public String getContent() { | ||
Object fieldObj = getResponseMapper().get("content"); | ||
String fieldValue = fieldObj == null || "".equals(fieldObj) ? null : fieldObj.toString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should " "
pass?
Use StringUtils.isNotEmpty()
or StringUtils.isNotBlank()
according to your answer
@brunoamancio Pretty cool mate! |
@footloosejava With these changes, accessing tangle-only and hybrid-hosted (tangle/internet) web content will be a reality. I have already implemented a simple IXI module (https://github.com/brunoamancio/TangleNet) to allow nodes provide that to clients sending requests directly from their browsers. I plan on developing it further to make this process as user-friendly as possible. |
@alon-e |
I will refactor the command logic in another PR. Until then, this PR will be left as is. |
@brunoamancio I'll review this shortly.
|
Answering @alon-e questions: 1 - In case the IXIResponse does not have the specific fields reserved for specifying the content and content-type of the response, the behavior is exactly as before. That means, only if code is like the following will this feature be used: ... javascript code of IXI module
That is done in the new method convertResponseToClientFormat in API.java Also, the method getResponseContentType makes sure the default content-type is json, like it is today. Only if it is explicitly defined by the IXIModule (in its response), will the response type be changed. Anyway, I can run those and tell you the results in a few days as well. 2 - The reason is that html content (and any other content format) is converted from the javascript-generated response from the IXI Module to IXIResponse using gson, which makes a desired response with html to be unreadable by the IRI client, since it's escaped. More details on gson in the API.java (where escaping is disabled):
There are no other usages of gson in the API.java class *Alternative: It would be possible to explicitly unescape IXIResponses before sending it to the client. But that would mean IRI knows what should be abstract to it (the content-type). 3 - I completely agree with that. I don't currently have time for the refactoring of the command logic, but if nothing is committed until I have time, I will do it myself in a separate PR and after the merge this PR can be updated with the better structure. |
Please don't delete this comment |
@brunoamancio |
Hi @GalRogozinski . I have not, yet. I'm really busy at work (.NET developer here) these last weeks and didn't have much free time after working hours either. Anyway, I will perform those tests asap, possibly this weekend. Update: |
…ledger#743) Updates old feature pull request improving X-IOTA-API-Version check management
Hi everyone, I'm interested in this topic. I opened a new PR (#1385) with some little improvements to keep discussing about it and I hope we could be able to eventually implement this feature. |
Description
This PR allows IXI Modules to decide the content-type they wish to send to the client. The idea is that clients might want to, for example, load web content directly on their browser, get data in XML format, images, or whatever the IXI module serves.
This PR was created for issue #615
Checklist: