1) Get file size
The request message has the form:
-
-<data_server_request>
- <core_client_major_version>1</core_client_major_version>
- <core_client_minor_version>1</core_client_minor_version>
- <get_file_size>filename</get_file_size>
-</data_server_request>
-
+ ", htmlspecialchars("
+
+ 1
+ 1
+ filename
+
+"), "
The reply message has the form:
-
-<data_server_reply>
- <status>x</status>
- [ <message>text</message>
- | <file_size>nbytes</file_size> ]
-</data_server_reply>
-
-Status is
-
+");
+list_item("-1", "Permanent error. The client should give up on the result.");
+list_end();
+echo "
In the error cases, the <file_size> element is omitted
and the <message> element gives an explanation.
2) Upload file
Request message format:
-
-<data_server_request>
-<core_client_major_version>1</core_client_major_version>
-<core_client_minor_version>1</core_client_minor_version>
-<file_upload>
-<file_info>
+ ", htmlspecialchars("
+
+1
+1
+
+
...
-<xml_signature>
+
...
-</xml_signature>
-</file_info>
-<nbytes>x</nbytes>
-<offset>x</offset>
-<data>
+
+
+x
+x
+
... (nbytes bytes of data; may include non-ASCII data)
-</data>
-
+
+"), "
The <file_info> element is the exact text sent from the
scheduling server to the client.
It includes a signature based on the project's file upload
authentication key pair.
-<nbytes> is the amount of data being uploaded.
+<nbytes> is the size of the file.
<offset> is the offset within the file.
Reply message format:
-
-<data_server_reply>
- <status>x</status>
- <message>text</message>
-</data_server_reply>
-
-Status is
-
In the error cases, the <message> element gives an explanation.
diff --git a/lib/parse.C b/lib/parse.C
index b14d028a22..e1d56aaa41 100644
--- a/lib/parse.C
+++ b/lib/parse.C
@@ -70,6 +70,7 @@ bool parse_double(const char* buf, const char* tag, double& x) {
// parse a string of the form ...string...;
// returns the "string" part.
+// "string" may not include '<'
// Strips white space from ends.
// Use "", if there might be attributes
//
@@ -78,14 +79,13 @@ bool parse_str(const char* buf, const char* tag, char* dest, int len) {
if (!p) return false;
p = strchr(p, '>');
++p;
- while (isspace(*p)) ++p;
char* q = strchr(p, '<');
if (!q) return false;
- while (isspace(*(q-1))) --q;
char save_q = *q;
*q = 0;
safe_strncpy(dest, p, len);
*q = save_q;
+ strip_whitespace(dest);
return true;
}
@@ -96,15 +96,15 @@ bool parse_str(const char* buf, const char* tag, string& dest) {
if (!p) return false;
p = strchr(p, '>');
++p;
- while (isspace(*p)) ++p;
char const* q = strchr(p, '<');
if (!q) return false;
- while (isspace(*(q-1))) --q;
dest.assign(p, q-p);
+ strip_whitespace(dest);
return true;
}
-// parse a string of the form name="string"
+// parse a string of the form name="string";
+// returns string in dest
//
void parse_attr(const char* buf, const char* name, char* dest, int len) {
char* p, *q;
diff --git a/lib/util.C b/lib/util.C
index 27930e8f10..c1a20dc05f 100755
--- a/lib/util.C
+++ b/lib/util.C
@@ -289,15 +289,34 @@ void c2x(char *what) {
strcpy(what, buf);
}
+// remove whitespace from start and end of a string
+//
void strip_whitespace(char *str) {
- int read_pos=0, write_pos=0;
- while (str[read_pos]) {
- if (!isspace(str[read_pos])) {
- str[write_pos++] = str[read_pos];
- }
- read_pos++;
+ int n;
+ while (isascii(str[0]) && isspace(str[0])) {
+ strcpy(str, str+1);
+ }
+ while (1) {
+ n = strlen(str);
+ if (n == 0) break;
+ if (!isascii(str[n-1])) break;
+ if (!isspace(str[n-1])) break;
+ str[n-1] = 0;
+ }
+}
+
+void strip_whitespace(string& str) {
+ int n;
+ while (isascii(str[0]) && isspace(str[0])) {
+ str.erase(0, 1);
+ }
+ while (1) {
+ n = str.length();
+ if (n == 0) break;
+ if (!isascii(str[n-1])) break;
+ if (!isspace(str[n-1])) break;
+ str.erase(n-1, 1);
}
- str[write_pos] = 0;
}
void unescape_url(char *url) {
diff --git a/lib/util.h b/lib/util.h
index dea729dd1c..21b71744b2 100755
--- a/lib/util.h
+++ b/lib/util.h
@@ -40,6 +40,7 @@ extern int parse_command_line( char *, char ** );
extern int lock_file(char*);
extern void c2x(char *what);
extern void strip_whitespace(char *str);
+extern void strip_whitespace(string&);
extern void unescape_url(char *url);
extern void escape_url(char *in, char*out);
extern void escape_url_readable(char* in, char* out);
@@ -62,19 +63,16 @@ inline bool starts_with(string const& s, string const& prefix) {
}
// http://lists.debian.org/debian-gcc/2002/debian-gcc-200204/msg00092.html
-inline void downcase_string(string::iterator begin, string::iterator end,
- string::iterator src)
-{
+inline void downcase_string(
+ string::iterator begin, string::iterator end, string::iterator src
+) {
std::transform(begin, end, src, (int(*)(int))tolower);
}
-inline void downcase_string(string& w)
-{
+inline void downcase_string(string& w) {
downcase_string(w.begin(), w.end(), w.begin());
}
-
-
// NOTE: use #include to get max,min
// the __attribute((format...)) tags are GCC extensions that let the compiler