Am 15.01.11 13:38, schrieb Carsten Schultz:
> Am 29.10.10 06:55, schrieb Steve Vinoski:
>> On Fri, Oct 29, 2010 at 12:38 AM, Steve Vinoski <vinoski@...> wrote:
>>> On Thu, Oct 28, 2010 at 8:18 PM, Steve Vinoski <vinoski@...> wrote:
>>>> On Thu, Oct 28, 2010 at 7:10 PM, Michael Foley <michaelf@...> wrote:
>>>>> I am trying to send the contents of a file using the {content, MimeType,
>>>>> Content} return value. I am having the problem that it is adding an extra
>>>>> byte to the end of the data. The extra byte is hex 0A, which is a linefeed
>>>>> character. Anyone else encounter this?
>>>>
>>>> I don't see it with the latest bits from github.
>>>
>>> Correction -- I do see the same problem. I wrote my attempt using a
>>> regular out/1 function and compiled it into a beam file, whereas
>>> Michael, you're using a .yaws file, which dawned on me when you sent
>>> me your code offline. I'm currently debugging where the extra data is
>>> coming from and will hopefully have it fixed shortly.
>>
>> OK, what's occurring is that since this is a .yaws file, the contents
>> of that file are delivered, minus the stuff between <erl>...</erl>
>> tags. In your case, your out/1 function first accumulates content to
>> be delivered via the {content, ...} construct, but when Yaws strips
>> the erl tags out of your .yaws file, it finds a "\n" at the end of the
>> file, following the </erl> tag, so that's added to the content to be
>> delivered as well.
>
> At least in my modified version version of 1.49 this is taken care of
> and this kind of white space is deleted. The code revolves around a
> function optimize_spec/2. I am not sure if I never contributed the code
> or of it got lost in the meantime, I suspect the latter. I probably
> should have documented it better to point out why it is desirable.
>
It seems that I never submitted these changes, I do not remember if
there was any reason for it. Anyway, here is (the relevant part of) a
diff against (I think) 1.49:
*** yaws_server.erl 6 Oct 2004 19:42:36 -0000 1.256
--- yaws_server.erl 15 Jan 2011 15:55:42 -0000
***************
*** 1412,1419 ****
{ok, [{errors, Errs}| Spec]} =
yaws_compile:compile_file(UT#urltype.fullpath),
?Debug("Spec for file ~s is:~n~p~n",[UT#urltype.fullpath, Spec]),
! ets:insert(SC#sconf.ets, {Key, spec, Mtime, Spec, Errs}),
! deliver_dyn_file(CliSock, Spec, ARG, UT, N)
end.
--- 1412,1421 ----
{ok, [{errors, Errs}| Spec]} =
yaws_compile:compile_file(UT#urltype.fullpath),
?Debug("Spec for file ~s is:~n~p~n",[UT#urltype.fullpath, Spec]),
! OptSpec = optimize_spec(UT, Spec),
! ?Debug("Optimized spec is:~n~p~n",[OptSpec]),
! ets:insert(SC#sconf.ets, {Key, spec, Mtime, OptSpec, Errs}),
! deliver_dyn_file(CliSock, OptSpec, ARG, UT, N)
end.
***************
*** 1526,1531 ****
--- 1528,1535 ----
%% do the header and continue
+ deliver_dyn_file(CliSock, Specs=[{mod, _, _, _, _, _}], ARG, UT, N) ->
+ deliver_dyn_file(CliSock, undefined, {bin, undefined}, Specs, ARG,
UT, N);
deliver_dyn_file(CliSock, Specs, ARG, UT, N) ->
Fd = ut_open(UT),
Bin = ut_read(Fd),
***************
*** 1696,1705 ****
--- 1700,1759 ----
done_or_continue().
+ %% optimize yaws specification
+
+ optimize_spec(UT, Spec) ->
+ FD = ut_open(UT),
+ Bin = ut_read(FD),
+ Spec1 = del_trailing_blanks(Bin, FD, Spec),
+ ut_close(FD),
+ case lists:any(fun({data, _}) ->
+ true;
+ ({error, _, _}) ->
+ true;
+ (_) -> false end, Spec1) of
+ true ->
+ Spec1;
+ false ->
+ lists:filter(fun({mod, _, _, _, _, _}) ->
+ true;
+ (_) -> false end, Spec1)
+ end.
+ del_trailing_blanks(_Bin, _FD, []) ->
+ [];
+ del_trailing_blanks(Bin, FD, [X={data, N}|T]) ->
+ {Bin1, Bin2} = skip_data(Bin, FD, N),
+ case lists:all(fun($\s) -> true;
+ ($\r) -> true;
+ ($\t) -> true;
+ ($\n) -> true;
+ (_) -> false end,
+ binary_to_list(to_binary(Bin1))) of
+ true ->
+ case del_trailing_blanks(Bin2, FD, T) of
+ [] ->
+ [];
+ L -> [X|L]
+ end;
+ false ->
+ [X|del_trailing_blanks(Bin2, FD, T)]
+ end;
+ del_trailing_blanks(Bin, FD, [X={skip, N}|T]) ->
+ {_Bin1, Bin2} = skip_data(Bin, FD, N),
+ [X|del_trailing_blanks(Bin2, FD, T)];
+ del_trailing_blanks(Bin, FD, [X={mod, _, _, N, _, _}|T]) ->
+ {_Bin1, Bin2} = skip_data(Bin, FD, N),
+ [X|del_trailing_blanks(Bin2, FD, T)];
+ del_trailing_blanks(_Bin, _FD, L) ->
+ L.
+
+
%% what about trailers ??
+ skip_data(undefined, _, _) ->
+ {undefined, undefined};
skip_data(List, Fd, Sz) when list(List) ->
skip_data(list_to_binary(List), Fd, Sz);
skip_data(Bin, Fd, Sz) when binary(Bin) ->
***************
*** 2596,2602 ****
clear_ets(E) ->
! ets:match_delete(E, {'_', spec, '_', '_', '_'}),
ets:match_delete(E, {{url, '_'}, '_', '_'}),
ets:match_delete(E, {{urlc, '_'}, '_', '_'}),
ets:insert(E, {num_files, 0}),
--- 2650,2656 ----
clear_ets(E) ->
! %%ets:match_delete(E, {'_', spec, '_', '_', '_'}),
ets:match_delete(E, {{url, '_'}, '_', '_'}),
ets:match_delete(E, {{urlc, '_'}, '_', '_'}),
ets:insert(E, {num_files, 0}),
I am not sure if the last section is related.
I did this change, because I like using .yaws files for almost
everything. Maybe it is useful to someone.
Best
Carsten
--
Carsten Schultz (2:38, 33:47)
http://carsten.codimi.de/
PGP/GPG key on the pgp.net key servers,
fingerprint on my home page.
|