Skip to content

Commit 17f5509

Browse files
author
Rik
committed
weboptions.m: Overhaul function.
* NEWS.11.md: Announce better Matlab compatibility with identical behavior for Timeout property. * weboptions.m: Rewrite documentation. Change UserAgent default from "GNU Octave/version" to "Octave/version" as IETF standard does not allow a space. Change default Timeout to 5 seconds for Matlab compatibility. Redo input validation to use simple for loop over input field names. Add FIXME notes about adding a call to warning() when an attempt is made to set an unimplemented field. Simplify if/error/else code by removing unnecessary else statement. * weboptions.m (set.Timeout): Implement support for "Inf". Change input validation to accept non-integer values. Validate that input is > 0 (subtly wrong code allowed 0 before which is not IETF standard). * weboptions.m (set.ContentReader): Validate that input is a function handle. * weboptions.m (display): Function deleted. * weboptions.m (disp): New function. Use num2str rather than int2str to display Timeout value. Add correct code to show ContentReader function handle.
1 parent 48691aa commit 17f5509

File tree

2 files changed

+95
-111
lines changed

2 files changed

+95
-111
lines changed

etc/NEWS.11.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ Summary of important user-visible changes for version 11 (yyyy-mm-dd):
9595
Octave scripts. The graphics properties `AxisLocation`, `Direction`, and
9696
`TickLabels` have been implemented.
9797

98+
- The `weboptions` has been re-written internally. Support for non-integer
99+
Timeout values, and the special value `Inf`, has been added.
100+
98101
- The `KeyEvent` structure passed as an input paramater to graphics callback
99102
functions such as `KeyPressFcn` now returns fieldnames in the same order
100103
as Matlab: `Character`, `Modifier`, `Key`.

scripts/web/weboptions.m

Lines changed: 92 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
classdef weboptions < handle
2727

2828
## -*- texinfo -*-
29-
## @deftypefn {} {@var{output} =} weboptions ()
30-
## @deftypefnx {} {@var{output} =} weboptions (@var{name1}, @var{value1}, @dots{})
29+
## @deftypefn {} {@var{options} =} weboptions ()
30+
## @deftypefnx {} {@var{options} =} weboptions (@var{name1}, @var{value1}, @dots{})
3131
##
3232
## Specify parameters for RESTful web services.
3333
##
34-
## @code{weboptions} with no inputs returns a default @code{weboptions}
35-
## object to specify parameters for a request to a web service. A
36-
## @code{weboptions} object can be an optional input argument to the
37-
## @code{webread} and @code{webwrite} functions.
34+
## When called with with no inputs return a default @code{weboptions} object
35+
## to specify parameters for a request to a web service. A @code{weboptions}
36+
## object is an optional input argument to the @code{webread} and
37+
## @code{webwrite} functions.
3838
##
3939
## Multiple name and value pair arguments may be specified in any order as
4040
## @var{name1}, @var{value1}, @var{name2}, @var{value2}, etc.
@@ -48,51 +48,55 @@
4848
## @item
4949
## @samp{CharacterEncoding} --- Specify the character encoding of the data:
5050
##
51-
## @samp{auto} (default), @samp{UTF-8}, @samp{US-ASCII}
51+
## @samp{auto} (default), @samp{UTF-8}, @samp{US-ASCII}.
5252
## @samp{auto} chooses an encoding based on the content-type of the data.
5353
##
5454
## @item
5555
## @samp{UserAgent} --- Specify the User Agent for the connection.
5656
##
57-
## Default value is @samp{GNU Octave/version}, where @samp{version} is the
57+
## Default value is @samp{Octave/version}, where @samp{version} is the
5858
## current version of Octave as returned by @code{version}.
5959
##
6060
## @item
6161
## @samp{Timeout} --- Specify the timeout value for the connection in
6262
## seconds.
6363
##
64-
## Default is 10 seconds. @samp{Inf} is not currently supported.
64+
## Default is 5 seconds. The special value @samp{Inf} sets the timeout to
65+
## the maximum value of 2147.483647 seconds.
6566
##
6667
## @item
6768
## @samp{Username} --- User identifier for a basic HTTP connection.
6869
##
69-
## Default is NULL@. It must be a string.
70+
## Default is @qcode{''}. It must be a string.
7071
##
7172
## @item
7273
## @samp{Password} --- User authentication password for HTTP connection.
7374
##
74-
## Default is NULL@. It must be a string or character vector.
75+
## Default is @qcode{''}. It must be a string or character vector.
76+
##
7577
## Programming Note: If you display a @code{weboption} object with the
7678
## Password property set, the value is displayed as a string containing
7779
## @qcode{'*'}. However, the object stores the value of the Password
7880
## property as plain text.
7981
##
8082
## @item
8183
## @samp{KeyName} --- Specify the name of an additional key to be added to
82-
## the HTTP request header. It should be coupled with @samp{KeyValue}. It
83-
## must be a string or character vector.
84+
## the HTTP request header.
85+
##
86+
## It must be a string or character vector. It should be coupled with
87+
## @samp{KeyValue}.
8488
##
8589
## @item
8690
## @samp{KeyValue} --- Specify the value of the key @samp{KeyName}.
8791
##
88-
## @samp{KeyName} must be present in order to assign to this field.
92+
## @samp{KeyName} must already be assigned in order to specify this field.
8993
##
9094
## @item
91-
## @samp{@nospell{HeaderFields}} --- Specify the header fields for the
95+
## @samp{@nospell{HeaderFields}} --- Specify header fields for the
9296
## connection.
9397
##
94-
## Names and values of header fields, specified as an m-by-2 array of strings
95-
## or cell array of character vectors to add to the HTTP request header.
98+
## Names and values of header fields, specified as an m-by-2 cell array of
99+
## strings, to add to the HTTP request header.
96100
## @code{@nospell{HeaderFields}@{i,1@}} is the name of a field and
97101
## @code{@nospell{HeaderFields}@{i,2@}} is its value.
98102
##
@@ -150,8 +154,8 @@
150154

151155
properties
152156
CharacterEncoding = "auto";
153-
UserAgent = ["GNU Octave/", version()];
154-
Timeout = 10;
157+
UserAgent = ["Octave/", version()];
158+
Timeout = 5;
155159
Username = "";
156160
Password = "";
157161
KeyName = "";
@@ -171,110 +175,87 @@
171175

172176
if (rem (numel (varargin), 2) != 0)
173177
error ("weboptions: invalid number of arguments");
174-
else
175-
h = cell2struct (varargin(2:2:end), varargin(1:2:end), 2);
176-
if (numfields (h) > 14)
177-
error ("weboptions: invalid number of arguments");
178-
endif
178+
elseif (numel (varargin) > 28)
179+
error ("weboptions: invalid number of arguments");
180+
endif
179181

180-
if (isfield (h, "CharacterEncoding"))
181-
f.CharacterEncoding = h.CharacterEncoding;
182-
h = rmfield (h, "CharacterEncoding");
183-
endif
182+
h = cell2struct (varargin(2:2:end), varargin(1:2:end), 2);
184183

185-
if (isfield (h, "UserAgent"))
186-
f.UserAgent = h.UserAgent;
187-
h = rmfield (h, "UserAgent");
188-
endif
184+
for fieldname = fieldnames (h)'
189185

190-
if (isfield (h, "Timeout"))
191-
f.Timeout = h.Timeout;
192-
h = rmfield (h, "Timeout");
193-
endif
186+
switch (fieldname{1})
194187

195-
if (isfield (h, "Username"))
196-
f.Username = h.Username;
197-
h = rmfield (h, "Username");
198-
endif
188+
case "CharacterEncoding"
189+
f.CharacterEncoding = h.CharacterEncoding;
199190

200-
if (isfield (h, "Password"))
201-
f.Password = h.Password;
202-
h = rmfield (h, "Password");
203-
endif
191+
case "UserAgent"
192+
f.UserAgent = h.UserAgent;
204193

205-
if (isfield (h, "KeyName"))
206-
f.KeyName = h.KeyName;
207-
h = rmfield (h, "KeyName");
208-
endif
194+
case "Timeout"
195+
f.Timeout = h.Timeout;
209196

210-
if (isfield (h, "KeyValue"))
211-
f.KeyValue = h.KeyValue;
212-
h = rmfield (h, "KeyValue");
213-
endif
197+
case "Username"
198+
f.Username = h.Username;
214199

215-
if (isfield (h, "HeaderFields"))
216-
f.HeaderFields = h.HeaderFields;
217-
h = rmfield (h, "HeaderFields");
218-
endif
200+
case "Password"
201+
f.Password = h.Password;
219202

220-
if (isfield (h, "ContentType"))
221-
f.ContentType = h.ContentType;
222-
h = rmfield (h, "ContentType");
223-
endif
203+
case "KeyName"
204+
f.KeyName = h.KeyName;
224205

225-
if (isfield (h, "ContentReader"))
226-
f.ContentReader = h.ContentReader;
227-
h = rmfield (h, "ContentReader");
228-
endif
206+
case "KeyValue"
207+
f.KeyValue = h.KeyValue;
229208

230-
if (isfield (h, "MediaType"))
231-
f.MediaType = h.MediaType;
232-
h = rmfield (h, "MediaType");
233-
endif
209+
case "HeaderFields"
210+
f.HeaderFields = h.HeaderFields;
234211

235-
if (isfield (h, "RequestMethod"))
236-
f.RequestMethod = h.RequestMethod;
237-
h = rmfield (h, "RequestMethod");
238-
endif
212+
case "ContentType"
213+
f.ContentType = h.ContentType;
239214

240-
if (isfield (h, "ArrayFormat"))
241-
f.ArrayFormat = h.ArrayFormat;
242-
h = rmfield (h, "ArrayFormat");
243-
endif
215+
case "ContentReader"
216+
f.ContentReader = h.ContentReader;
244217

245-
if (isfield (h, "CertificateFilename"))
246-
f.CertificateFilename = h.CertificateFilename;
247-
h = rmfield (h, "CertificateFilename");
248-
endif
218+
case "MediaType"
219+
f.MediaType = h.MediaType;
249220

250-
if (! isempty (fieldnames (h)))
251-
field = fieldnames (h){1};
252-
error (["weboptions: Undefined field " field]);
253-
endif
254-
endif
221+
case "RequestMethod"
222+
f.RequestMethod = h.RequestMethod;
223+
224+
case "ArrayFormat"
225+
f.ArrayFormat = h.ArrayFormat;
226+
227+
case "CertificateFilename"
228+
f.CertificateFilename = h.CertificateFilename;
229+
230+
otherwise
231+
error ("weboptions: Undefined field '%s'", field);
232+
233+
endswitch
234+
endfor
255235

256236
endfunction
257237

258238
function f = set.CharacterEncoding (f, value)
259-
if (! any (strcmpi (value, {"UTF-8", 'US-ASCII', "auto"})))
239+
## FIXME: Why validate this? There are many other possible encodings.
240+
if (! any (strcmpi (value, {'auto', 'US-ASCII', 'UTF-8'})))
260241
error ("weboptions: Invalid CharacterEncoding value");
261-
else
262-
f.CharacterEncoding = value;
263242
endif
243+
f.CharacterEncoding = value;
264244
endfunction
265245

266246
function f = set.UserAgent (f, value)
267247
if (! ischar (value) && ! isrow (value))
268248
error ("weboptions: UserAgent must be a string");
269-
else
270-
f.UserAgent = value;
271249
endif
250+
f.UserAgent = value;
272251
endfunction
273252

274253
function f = set.Timeout (f, value)
275-
if (! isreal (value) || ! isscalar (value)
276-
|| floor (value) != value || value < 0)
277-
error ("weboptions: invalid Timeout value");
254+
if (! (isreal (value) && isscalar (value) && value > 0))
255+
error ("weboptions: Timeout must be a real scalar > 0");
256+
endif
257+
if (value == Inf)
258+
f.Timeout = 2147.483647;
278259
else
279260
f.Timeout = value;
280261
endif
@@ -283,33 +264,29 @@
283264
function f = set.Username (f, value)
284265
if (! ischar (value) && ! isrow (value))
285266
error ("weboptions: Username must be a string");
286-
else
287-
f.Username = value;
288267
endif
268+
f.Username = value;
289269
endfunction
290270

291271
function f = set.Password (f, value)
292272
if (! ischar (value) && ! isrow (value))
293273
error ("weboptions: Password must be a string");
294-
else
295-
f.Password = value;
296274
endif
275+
f.Password = value;
297276
endfunction
298277

299278
function f = set.KeyName (f, value)
300279
if (! ischar (value) && ! isrow (value))
301280
error ("weboptions: invalid KeyName value");
302-
else
303-
f.KeyName = value;
304281
endif
282+
f.KeyName = value;
305283
endfunction
306284

307285
function f = set.KeyValue (f, value)
308286
if (isempty (f.KeyName) && ! isempty (value))
309-
error ("weboptions: field KeyName empty. Cannot set KeyValue.");
310-
else
311-
f.KeyValue = value;
287+
error ("weboptions: KeyName field empty. Cannot set KeyValue.");
312288
endif
289+
f.KeyValue = value;
313290
endfunction
314291

315292
function f = set.HeaderFields (f, value)
@@ -336,18 +313,22 @@
336313
endfunction
337314

338315
function f = set.ContentReader (f, value)
316+
if (! is_function_handle (value))
317+
error ("weboptions: ContentReader must be a function handle");
318+
endif
319+
## FIXME: Should emit a warning about unimplemented feature
339320
f.ContentReader = value;
340321
endfunction
341322

342323
function f = set.MediaType (f, value)
324+
## FIXME: Should emit a warning about unimplemented feature
343325
f.MediaType = value;
344326
endfunction
345327

346328
function f = set.RequestMethod (f, value)
347-
348329
if (! isempty (value))
349-
if (! any (strcmpi (value, {"auto", "get", "put", "post",...
350-
"delete", "patch"})))
330+
if (! any (strcmpi (value,
331+
{"auto", "get", "put", "post", "delete", "patch"})))
351332
error ("weboptions: invalid RequestMethod value");
352333
endif
353334
endif
@@ -365,16 +346,17 @@
365346
endfunction
366347

367348
function f = set.CertificateFilename (f, value)
349+
## FIXME: Should emit a warning about unimplemented feature
368350
f.CertificateFilename = value;
369351
endfunction
370352

371-
function display (f)
353+
function disp (f)
372354

373-
Timeout = int2str (f.Timeout);
355+
Timeout = num2str (f.Timeout);
374356
Password = repmat ("*", 1, numel (num2str (f.Password)));
375357

376358
if (! isempty (f.ContentReader))
377-
ContentReader = ['["', strjoin(f.ContentReader, '", "'), '"]'];
359+
ContentReader = disp (f.ContentReader);
378360
else
379361
ContentReader = "[]";
380362
endif
@@ -391,8 +373,7 @@ function display (f)
391373
KeyValue = "''";
392374
endif
393375

394-
printf ("%s =", inputname (1));
395-
output = ["\n\n weboptions with properties: \n",...
376+
output = [" weboptions with properties:\n",...
396377
"\n CharacterEncoding: '", f.CharacterEncoding, "'",...
397378
"\n UserAgent: '", f.UserAgent, "'",...
398379
"\n Timeout: " , Timeout, "",...
@@ -406,7 +387,7 @@ function display (f)
406387
"\n RequestMethod: '", f.RequestMethod, "'",...
407388
"\n ArrayFormat: '", f.ArrayFormat, "'",...
408389
"\n HeaderFields: " , HeaderFields,...
409-
"\n CertificateFilename: '", f.CertificateFilename, "'\n"];
390+
"\n CertificateFilename: '", f.CertificateFilename];
410391
disp (output);
411392

412393
endfunction

0 commit comments

Comments
 (0)