-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
http_reply: please add support for http_reply(codes(Cs), ...) #9
Comments
I have my doubts. For example,
|
Ideally, I want to reply simply with:
So, if possible, I would like to avoid using |
Using Using the approach I proposed copies a lot less and even allows passing the data as it arrives if we use chunked encoding or a closed connection. Keep-alive is indeed not provided by the current |
One requirement I also have: The proxy cannot just blindly copy everything that the target URL emits. Redirections are an example where rewriting of the emitted content is necessary, because the target web server emits URL redirections from its own point of view, yet the new target goals need to make sense in terms of the proxy's view, where the target service can be made available under a different umbrella URL, and redirections must match that. In #11, you suggest the new option |
I have now tried the
The reverse proxy parses this reply correctly: I see from debug messages that But alas, invariably the charset HTTP/1.1 200 OK Date: Tue, 03 Nov 2015 22:31:55 GMT Content-Type: text/html; charset=UTF-8 Connection: close Content-Length: 376 and somewhere in this translation the UTF-8 encoded characters seem to be accidentally encoded twice. The main code snippet I use to relay the message from the target server to the client is:
I guess I need to set a stream option so that the content type is not changed? The rudimentary reverse proxy implementation is available as Proloxy. Wouter and you now have write access, please feel free to try any changes if you want to experiment with this. In my experience, the reverse proxy helps to catch many edge cases regarding encodings and missing options to handle different use cases of the HTTP libraries. |
There is probably no clean way out. The contract is that text in Prolog is Unicode and if you need to send it it will be sent as UTF-8, being the only encoding that unambiguously represents all of Unicode, is supported by Prolog as well as all at least somewhat maintained clients. You want to formulate a request using bytes with an unknown encoding that you claim to be text. The correct approach in the HTTP framework would be to discover the encoding of the source and translate it to Unicode (and consequently write the output as UTF-8). The only way out is to dump bytes and claim some content type for them is using the throw(http_reply(...)) interface. I added :- use_module(library(http/http_open)).
:- use_module(library(http/http_client)).
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
server(Port) :-
http_server(http_dispatch,
[ port(Port)
]).
:- http_handler(/, proxy('http://localhost:3050'), [prefix]).
proxy(To, Request) :-
memberchk(method(Method), Request),
proxy(Method, To, Request).
proxy(Method, To, Request) :-
data_method(Method), !,
read_data(Request, Data),
memberchk(request_uri(URI), Request),
atomic_list_concat([To,URI], Target),
http_open(Target, In,
[ method(Method),
post(Data),
header(content_type, ContentType)
]),
call_cleanup(
read_string(In, _, Bytes),
close(In)),
throw(http_reply(bytes(ContentType, Bytes))).
proxy(Method, To, Request) :-
memberchk(request_uri(URI), Request),
atomic_list_concat([To,URI], Target),
http_open(Target, In,
[ method(Method),
header(content_type, ContentType)
]),
call_cleanup(
read_string(In, _, Bytes),
close(In)),
throw(http_reply(bytes(ContentType, Bytes))).
read_data(Request, bytes(ContentType, Bytes)) :-
memberchk(input(In), Request),
memberchk(content_type(ContentType), Request),
( memberchk(content_length(Len), Request)
-> read_string(In, Len, Bytes)
; read_string(In, _, Bytes)
).
data_method(post).
data_method(put). |
Many thanks Jan, this is a truly awesome improvement! Could you please also account for this in the logging infrastructure, so that we see more compact log entries when bytes are emitted? I got it working by adding the following at the end of
Otherwise, we see lots of completed(1, 0.001994, 8, 200, bytes('text/plain',8)). |
Added the log change. Dunno about the https thing. You'll have to understand the exact traffic and |
Thank you for adding |
It would be very useful to reply from a list of codes using
http_reply(codes(Cs), ...)
, especially sincehttp_get/3
already supports reading to a list of codes. Please consider supporting this.My immediate use case is the implementation of a simple reverse HTTP proxy: I query existing HTTP servers and relay their responses to the client. I can use a memory file for this, but would prefer to simply use a list of codes.
The text was updated successfully, but these errors were encountered: