diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-01 09:03:53 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-01 09:03:53 +0200 |
commit | de48da0eb43e7b3893dca11d1f50928d5a412c1e (patch) | |
tree | ad90621000b63c1e039c1e2550e9d875443f0d72 | |
parent | 784c82eba152733531acfb1213e64736a61c8c07 (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.
-rw-r--r-- | src/gmrequest.c | 38 |
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) { |