Can not catch HttpMethod: OPTIONS on a http request
I'm writing an ActionFilterAttribute where I check userId route/query parameters and compare it against the subject of a jwt token. I noticed that my Action Filter gets triggered twice. In chrome I can see that an OPTIONS request is sent to the server and in my debug console output I can see the call with the correct http method:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
But when it hits my Action Filter, Http Method is always set as GET so I can not make my filter return on an OPTIONS call.
Here is a basic OnActionExecutionAsync override method:
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
Debug.WriteLine("URL CALL: " + context.HttpContext.Request.GetDisplayUrl());
Debug.WriteLine("HTTP METHOD: " + context.HttpContext.Request.Method);
if (HttpMethods.IsOptions(context.HttpContext.Request.Method))
{
Debug.WriteLine("HTTP METHOD: OPTIONS");
return base.OnActionExecutionAsync(context, next);
}
// Other Code ....
}
The debug log:
URL CALL: http://localhost:5000/api/v1/users/33417
HTTP METHOD: GET
URL CALL: http://localhost:5000/api/v1/users/33417
HTTP METHOD: GET
Another interesting point is that if I request OPTIONS from Postman tool my API returns this error message:
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'http://localhost:5000/api/v1/users/33417' with API version '1' does not support HTTP method 'OPTIONS'.",
"innerError": null
}
}
Here is my Cors Configuration in Startup:
services.AddCors(options => options.AddPolicy(_constants.CorsPolicy,
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.Build()));
Is there any way I can catch the OPTIONS http method in my Action Filter?
c# asp.net-web-api asp.net-core .net-core actionfilterattribute
add a comment |
I'm writing an ActionFilterAttribute where I check userId route/query parameters and compare it against the subject of a jwt token. I noticed that my Action Filter gets triggered twice. In chrome I can see that an OPTIONS request is sent to the server and in my debug console output I can see the call with the correct http method:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
But when it hits my Action Filter, Http Method is always set as GET so I can not make my filter return on an OPTIONS call.
Here is a basic OnActionExecutionAsync override method:
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
Debug.WriteLine("URL CALL: " + context.HttpContext.Request.GetDisplayUrl());
Debug.WriteLine("HTTP METHOD: " + context.HttpContext.Request.Method);
if (HttpMethods.IsOptions(context.HttpContext.Request.Method))
{
Debug.WriteLine("HTTP METHOD: OPTIONS");
return base.OnActionExecutionAsync(context, next);
}
// Other Code ....
}
The debug log:
URL CALL: http://localhost:5000/api/v1/users/33417
HTTP METHOD: GET
URL CALL: http://localhost:5000/api/v1/users/33417
HTTP METHOD: GET
Another interesting point is that if I request OPTIONS from Postman tool my API returns this error message:
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'http://localhost:5000/api/v1/users/33417' with API version '1' does not support HTTP method 'OPTIONS'.",
"innerError": null
}
}
Here is my Cors Configuration in Startup:
services.AddCors(options => options.AddPolicy(_constants.CorsPolicy,
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.Build()));
Is there any way I can catch the OPTIONS http method in my Action Filter?
c# asp.net-web-api asp.net-core .net-core actionfilterattribute
Do you have CORS configured on the project?
– juunas
Nov 20 '18 at 8:34
Yes, it is configured toAllowAnyMethod()
– Tarik Tutuncu
Nov 20 '18 at 8:36
1
Then that's the answer, the CORS middleware is handling the OPTIONS request, and what your filter sees is the GET request that follows the OPTIONS request.
– juunas
Nov 20 '18 at 8:42
add a comment |
I'm writing an ActionFilterAttribute where I check userId route/query parameters and compare it against the subject of a jwt token. I noticed that my Action Filter gets triggered twice. In chrome I can see that an OPTIONS request is sent to the server and in my debug console output I can see the call with the correct http method:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
But when it hits my Action Filter, Http Method is always set as GET so I can not make my filter return on an OPTIONS call.
Here is a basic OnActionExecutionAsync override method:
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
Debug.WriteLine("URL CALL: " + context.HttpContext.Request.GetDisplayUrl());
Debug.WriteLine("HTTP METHOD: " + context.HttpContext.Request.Method);
if (HttpMethods.IsOptions(context.HttpContext.Request.Method))
{
Debug.WriteLine("HTTP METHOD: OPTIONS");
return base.OnActionExecutionAsync(context, next);
}
// Other Code ....
}
The debug log:
URL CALL: http://localhost:5000/api/v1/users/33417
HTTP METHOD: GET
URL CALL: http://localhost:5000/api/v1/users/33417
HTTP METHOD: GET
Another interesting point is that if I request OPTIONS from Postman tool my API returns this error message:
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'http://localhost:5000/api/v1/users/33417' with API version '1' does not support HTTP method 'OPTIONS'.",
"innerError": null
}
}
Here is my Cors Configuration in Startup:
services.AddCors(options => options.AddPolicy(_constants.CorsPolicy,
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.Build()));
Is there any way I can catch the OPTIONS http method in my Action Filter?
c# asp.net-web-api asp.net-core .net-core actionfilterattribute
I'm writing an ActionFilterAttribute where I check userId route/query parameters and compare it against the subject of a jwt token. I noticed that my Action Filter gets triggered twice. In chrome I can see that an OPTIONS request is sent to the server and in my debug console output I can see the call with the correct http method:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
But when it hits my Action Filter, Http Method is always set as GET so I can not make my filter return on an OPTIONS call.
Here is a basic OnActionExecutionAsync override method:
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
Debug.WriteLine("URL CALL: " + context.HttpContext.Request.GetDisplayUrl());
Debug.WriteLine("HTTP METHOD: " + context.HttpContext.Request.Method);
if (HttpMethods.IsOptions(context.HttpContext.Request.Method))
{
Debug.WriteLine("HTTP METHOD: OPTIONS");
return base.OnActionExecutionAsync(context, next);
}
// Other Code ....
}
The debug log:
URL CALL: http://localhost:5000/api/v1/users/33417
HTTP METHOD: GET
URL CALL: http://localhost:5000/api/v1/users/33417
HTTP METHOD: GET
Another interesting point is that if I request OPTIONS from Postman tool my API returns this error message:
{
"error": {
"code": "UnsupportedApiVersion",
"message": "The HTTP resource that matches the request URI 'http://localhost:5000/api/v1/users/33417' with API version '1' does not support HTTP method 'OPTIONS'.",
"innerError": null
}
}
Here is my Cors Configuration in Startup:
services.AddCors(options => options.AddPolicy(_constants.CorsPolicy,
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.Build()));
Is there any way I can catch the OPTIONS http method in my Action Filter?
c# asp.net-web-api asp.net-core .net-core actionfilterattribute
c# asp.net-web-api asp.net-core .net-core actionfilterattribute
edited Nov 20 '18 at 11:11
Tarik Tutuncu
asked Nov 20 '18 at 8:32
Tarik TutuncuTarik Tutuncu
46329
46329
Do you have CORS configured on the project?
– juunas
Nov 20 '18 at 8:34
Yes, it is configured toAllowAnyMethod()
– Tarik Tutuncu
Nov 20 '18 at 8:36
1
Then that's the answer, the CORS middleware is handling the OPTIONS request, and what your filter sees is the GET request that follows the OPTIONS request.
– juunas
Nov 20 '18 at 8:42
add a comment |
Do you have CORS configured on the project?
– juunas
Nov 20 '18 at 8:34
Yes, it is configured toAllowAnyMethod()
– Tarik Tutuncu
Nov 20 '18 at 8:36
1
Then that's the answer, the CORS middleware is handling the OPTIONS request, and what your filter sees is the GET request that follows the OPTIONS request.
– juunas
Nov 20 '18 at 8:42
Do you have CORS configured on the project?
– juunas
Nov 20 '18 at 8:34
Do you have CORS configured on the project?
– juunas
Nov 20 '18 at 8:34
Yes, it is configured to
AllowAnyMethod()
– Tarik Tutuncu
Nov 20 '18 at 8:36
Yes, it is configured to
AllowAnyMethod()
– Tarik Tutuncu
Nov 20 '18 at 8:36
1
1
Then that's the answer, the CORS middleware is handling the OPTIONS request, and what your filter sees is the GET request that follows the OPTIONS request.
– juunas
Nov 20 '18 at 8:42
Then that's the answer, the CORS middleware is handling the OPTIONS request, and what your filter sees is the GET request that follows the OPTIONS request.
– juunas
Nov 20 '18 at 8:42
add a comment |
1 Answer
1
active
oldest
votes
Since you have CORS setup on the app,
it responds to the OPTIONS pre-flight request before MVC.
That request never gets to MVC, so your filter cannot see it.
What your filter sees is the GET request that comes after the OPTIONS request.
app.UseCors(); //Sees OPTIONS request, sets response and returns
app.UseMvc();
Ok I understand this but there is a different situation, in my debug log I can see 2 incoming requests:Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
I put a debug log on the action filter and the action filter triggers twice both with GET Http method. Looks like the OPTIONS method gets converted to GET method.
– Tarik Tutuncu
Nov 20 '18 at 10:42
Can you check the URL on both of them in the action filter?
– juunas
Nov 20 '18 at 10:45
1
I put a debug log:URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET
Same URL's are called
– Tarik Tutuncu
Nov 20 '18 at 10:58
That's pretty odd then. Be sure to add those things to your question.
– juunas
Nov 20 '18 at 11:02
I have updated my question thanks
– Tarik Tutuncu
Nov 20 '18 at 11:16
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53388973%2fcan-not-catch-httpmethod-options-on-a-http-request%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Since you have CORS setup on the app,
it responds to the OPTIONS pre-flight request before MVC.
That request never gets to MVC, so your filter cannot see it.
What your filter sees is the GET request that comes after the OPTIONS request.
app.UseCors(); //Sees OPTIONS request, sets response and returns
app.UseMvc();
Ok I understand this but there is a different situation, in my debug log I can see 2 incoming requests:Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
I put a debug log on the action filter and the action filter triggers twice both with GET Http method. Looks like the OPTIONS method gets converted to GET method.
– Tarik Tutuncu
Nov 20 '18 at 10:42
Can you check the URL on both of them in the action filter?
– juunas
Nov 20 '18 at 10:45
1
I put a debug log:URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET
Same URL's are called
– Tarik Tutuncu
Nov 20 '18 at 10:58
That's pretty odd then. Be sure to add those things to your question.
– juunas
Nov 20 '18 at 11:02
I have updated my question thanks
– Tarik Tutuncu
Nov 20 '18 at 11:16
add a comment |
Since you have CORS setup on the app,
it responds to the OPTIONS pre-flight request before MVC.
That request never gets to MVC, so your filter cannot see it.
What your filter sees is the GET request that comes after the OPTIONS request.
app.UseCors(); //Sees OPTIONS request, sets response and returns
app.UseMvc();
Ok I understand this but there is a different situation, in my debug log I can see 2 incoming requests:Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
I put a debug log on the action filter and the action filter triggers twice both with GET Http method. Looks like the OPTIONS method gets converted to GET method.
– Tarik Tutuncu
Nov 20 '18 at 10:42
Can you check the URL on both of them in the action filter?
– juunas
Nov 20 '18 at 10:45
1
I put a debug log:URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET
Same URL's are called
– Tarik Tutuncu
Nov 20 '18 at 10:58
That's pretty odd then. Be sure to add those things to your question.
– juunas
Nov 20 '18 at 11:02
I have updated my question thanks
– Tarik Tutuncu
Nov 20 '18 at 11:16
add a comment |
Since you have CORS setup on the app,
it responds to the OPTIONS pre-flight request before MVC.
That request never gets to MVC, so your filter cannot see it.
What your filter sees is the GET request that comes after the OPTIONS request.
app.UseCors(); //Sees OPTIONS request, sets response and returns
app.UseMvc();
Since you have CORS setup on the app,
it responds to the OPTIONS pre-flight request before MVC.
That request never gets to MVC, so your filter cannot see it.
What your filter sees is the GET request that comes after the OPTIONS request.
app.UseCors(); //Sees OPTIONS request, sets response and returns
app.UseMvc();
answered Nov 20 '18 at 8:43
juunasjuunas
22k34880
22k34880
Ok I understand this but there is a different situation, in my debug log I can see 2 incoming requests:Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
I put a debug log on the action filter and the action filter triggers twice both with GET Http method. Looks like the OPTIONS method gets converted to GET method.
– Tarik Tutuncu
Nov 20 '18 at 10:42
Can you check the URL on both of them in the action filter?
– juunas
Nov 20 '18 at 10:45
1
I put a debug log:URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET
Same URL's are called
– Tarik Tutuncu
Nov 20 '18 at 10:58
That's pretty odd then. Be sure to add those things to your question.
– juunas
Nov 20 '18 at 11:02
I have updated my question thanks
– Tarik Tutuncu
Nov 20 '18 at 11:16
add a comment |
Ok I understand this but there is a different situation, in my debug log I can see 2 incoming requests:Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
I put a debug log on the action filter and the action filter triggers twice both with GET Http method. Looks like the OPTIONS method gets converted to GET method.
– Tarik Tutuncu
Nov 20 '18 at 10:42
Can you check the URL on both of them in the action filter?
– juunas
Nov 20 '18 at 10:45
1
I put a debug log:URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET
Same URL's are called
– Tarik Tutuncu
Nov 20 '18 at 10:58
That's pretty odd then. Be sure to add those things to your question.
– juunas
Nov 20 '18 at 11:02
I have updated my question thanks
– Tarik Tutuncu
Nov 20 '18 at 11:16
Ok I understand this but there is a different situation, in my debug log I can see 2 incoming requests:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
I put a debug log on the action filter and the action filter triggers twice both with GET Http method. Looks like the OPTIONS method gets converted to GET method.– Tarik Tutuncu
Nov 20 '18 at 10:42
Ok I understand this but there is a different situation, in my debug log I can see 2 incoming requests:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417 Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json
I put a debug log on the action filter and the action filter triggers twice both with GET Http method. Looks like the OPTIONS method gets converted to GET method.– Tarik Tutuncu
Nov 20 '18 at 10:42
Can you check the URL on both of them in the action filter?
– juunas
Nov 20 '18 at 10:45
Can you check the URL on both of them in the action filter?
– juunas
Nov 20 '18 at 10:45
1
1
I put a debug log:
URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET
Same URL's are called– Tarik Tutuncu
Nov 20 '18 at 10:58
I put a debug log:
URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET URL CALL: http://localhost:5000/api/v1/users/33417 HTTP METHOD: GET
Same URL's are called– Tarik Tutuncu
Nov 20 '18 at 10:58
That's pretty odd then. Be sure to add those things to your question.
– juunas
Nov 20 '18 at 11:02
That's pretty odd then. Be sure to add those things to your question.
– juunas
Nov 20 '18 at 11:02
I have updated my question thanks
– Tarik Tutuncu
Nov 20 '18 at 11:16
I have updated my question thanks
– Tarik Tutuncu
Nov 20 '18 at 11:16
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53388973%2fcan-not-catch-httpmethod-options-on-a-http-request%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Do you have CORS configured on the project?
– juunas
Nov 20 '18 at 8:34
Yes, it is configured to
AllowAnyMethod()
– Tarik Tutuncu
Nov 20 '18 at 8:36
1
Then that's the answer, the CORS middleware is handling the OPTIONS request, and what your filter sees is the GET request that follows the OPTIONS request.
– juunas
Nov 20 '18 at 8:42