summaryrefslogtreecommitdiff
path: root/src/gmrequest.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-12-01 09:03:53 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-12-01 09:03:53 +0200
commitde48da0eb43e7b3893dca11d1f50928d5a412c1e (patch)
treead90621000b63c1e039c1e2550e9d875443f0d72 /src/gmrequest.c
parent784c82eba152733531acfb1213e64736a61c8c07 (diff)
GmRequest: Parsing the header
Use a regexp to parse the received header. This is better for recognizing invalid headers, e.g., gemini://gemini.conman.org/test/torture/0039.
Diffstat (limited to 'src/gmrequest.c')
-rw-r--r--src/gmrequest.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/src/gmrequest.c b/src/gmrequest.c
index 64e168a6..b51d3b1f 100644
--- a/src/gmrequest.c
+++ b/src/gmrequest.c
@@ -181,28 +181,36 @@ static void readIncoming_GmRequest_(iGmRequest *d, iTlsRequest *req) {
181 constBegin_String(&resp->meta) + endPos + 2, 181 constBegin_String(&resp->meta) + endPos + 2,
182 size_String(&resp->meta) - endPos - 2); 182 size_String(&resp->meta) - endPos - 2);
183 remove_Block(&resp->meta.chars, endPos, iInvalidSize); 183 remove_Block(&resp->meta.chars, endPos, iInvalidSize);
184 /* parse and remove the code */ 184 /* Parse and remove the code. */
185 if (size_String(&resp->meta) < 3) { 185 iRegExp *metaPattern = new_RegExp("^([0-9][0-9])(( )(.*))?", 0);
186 clear_String(&resp->meta); 186 /* TODO: Empty <META> means no <SPACE>? Not according to the spec? */
187 resp->statusCode = invalidHeader_GmStatusCode; 187 iRegExpMatch m;
188 d->state = finished_GmRequestState; 188 init_RegExpMatch(&m);
189 notifyDone = iTrue; 189 int code = 0;
190 if (matchString_RegExp(metaPattern, &resp->meta, &m)) {
191 code = atoi(capturedRange_RegExpMatch(&m, 1).start);
192 remove_Block(&resp->meta.chars,
193 0,
194 capturedRange_RegExpMatch(&m, 1).end -
195 constBegin_String(&resp->meta)); /* leave just the <META> */
196 trimStart_String(&resp->meta);
190 } 197 }
191 const int code = toInt_String(&resp->meta);
192 if (code == 0) { 198 if (code == 0) {
193 clear_String(&resp->meta); 199 clear_String(&resp->meta);
194 resp->statusCode = invalidHeader_GmStatusCode; 200 resp->statusCode = invalidHeader_GmStatusCode;
195 d->state = finished_GmRequestState; 201 d->state = finished_GmRequestState;
196 notifyDone = iTrue; 202 notifyDone = iTrue;
197 } 203 }
198 remove_Block(&resp->meta.chars, 0, 3); /* just the meta */ 204 else {
199 if (code == success_GmStatusCode && isEmpty_String(&resp->meta)) { 205 if (code == success_GmStatusCode && isEmpty_String(&resp->meta)) {
200 setCStr_String(&resp->meta, "text/gemini; charset=utf-8"); /* default */ 206 setCStr_String(&resp->meta, "text/gemini; charset=utf-8"); /* default */
207 }
208 resp->statusCode = code;
209 d->state = receivingBody_GmRequestState;
210 notifyUpdate = iTrue;
201 } 211 }
202 resp->statusCode = code;
203 d->state = receivingBody_GmRequestState;
204 checkServerCertificate_GmRequest_(d); 212 checkServerCertificate_GmRequest_(d);
205 notifyUpdate = iTrue; 213 iRelease(metaPattern);
206 } 214 }
207 } 215 }
208 else if (d->state == receivingBody_GmRequestState) { 216 else if (d->state == receivingBody_GmRequestState) {